/** * Product form * * @Template * @param int $id The product ID * @param Request $request * @return array Template vars */ public function formAction($id, Request $request) { $productAdapter = $this->container->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'); $legacyContext = $legacyContextService->getContext(); $isMultiShopContext = count($shopContext->getContextListShopID()) > 1 ? true : false; // Redirect to legacy controller (FIXME: temporary behavior) $pagePreference = $this->container->get('prestashop.core.admin.page_preference_interface'); /* @var $pagePreference AdminPagePreferenceInterface */ if ($pagePreference->getTemporaryShouldUseLegacyPage('product')) { $legacyUrlGenerator = $this->container->get('prestashop.core.admin.url_generator_legacy'); /* @var $legacyUrlGenerator UrlGeneratorInterface */ return $this->redirect($legacyUrlGenerator->generate('admin_product_form', array('id' => $id)), 302); } $response = new JsonResponse(); $modelMapper = new ProductAdminModelAdapter($product, $this->container->get('prestashop.adapter.legacy.context'), $this->container->get('prestashop.adapter.admin.wrapper.product'), $this->container->get('prestashop.adapter.tools'), $productAdapter, $this->container->get('prestashop.adapter.data_provider.supplier'), $this->container->get('prestashop.adapter.data_provider.warehouse'), $this->container->get('prestashop.adapter.data_provider.feature'), $this->container->get('prestashop.adapter.data_provider.pack'), $this->container->get('prestashop.adapter.shop.context')); $adminProductWrapper = $this->container->get('prestashop.adapter.admin.wrapper.product'); $form = $this->createFormBuilder($modelMapper->getFormData())->add('id_product', 'Symfony\\Component\\Form\\Extension\\Core\\Type\\HiddenType')->add('step1', 'PrestaShopBundle\\Form\\Admin\\Product\\ProductInformation')->add('step2', 'PrestaShopBundle\\Form\\Admin\\Product\\ProductPrice')->add('step3', 'PrestaShopBundle\\Form\\Admin\\Product\\ProductQuantity')->add('step4', 'PrestaShopBundle\\Form\\Admin\\Product\\ProductShipping')->add('step5', 'PrestaShopBundle\\Form\\Admin\\Product\\ProductSeo')->add('step6', 'PrestaShopBundle\\Form\\Admin\\Product\\ProductOptions')->getForm(); $formBulkCombinations = $this->createForm('PrestaShopBundle\\Form\\Admin\\Product\\ProductCombinationBulk', null, array('iso_code' => $this->get('prestashop.adapter.legacy.context')->getContext()->currency->iso_code, 'price_display_precision' => $this->configuration->get('_PS_PRICE_DISPLAY_PRECISION_'))); $form->handleRequest($request); $formData = $form->getData(); if ($form->isSubmitted()) { if ($form->isValid()) { // Legacy code. To fix when Object model will change. But report Hooks. $postData = $request->request->all(); $combinations = array(); foreach ((array) $postData as $postKey => $postValue) { if (preg_match('/^combination_.*/', $postKey)) { $combinations[$postKey] = $postValue; } } $formData['step3']['combinations'] = $combinations; //define POST values for keeping legacy adminController skills $_POST = $modelMapper->getModelData($formData, $isMultiShopContext) + $_POST; $_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 if ($product = $adminProductController->postCoreProcess()) { $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 is managed for the whole product (as combination ID 0) // In all cases, legacy hooks are triggered: actionProductUpdate and actionUpdateQuantity if (count($_POST['combinations']) === 0) { $adminProductWrapper->processQuantityUpdate($product, $_POST['qty_0']); } // else quantities are managed from $adminProductWrapper->processProductAttribute() above. $adminProductWrapper->processProductOutOfStock($product, $_POST['out_of_stock']); $adminProductWrapper->processProductCustomization($product, $_POST['custom_fields']); $adminProductWrapper->processAttachments($product, $_POST['attachments']); $adminProductController->processWarehouses(); $response->setData(['product' => $product]); } if ($request->isXmlHttpRequest()) { return $response; } } elseif ($request->isXmlHttpRequest()) { $response->setStatusCode(400); $response->setData($this->getFormErrorsForJS($form)); return $response; } } $stockManager = $this->container->get('prestashop.core.data_provider.stock_interface'); /* @var $stockManager StockInterface */ $warehouseProvider = $this->container->get('prestashop.adapter.data_provider.warehouse'); /* @var $warehouseProvider WarehouseDataProvider */ //If context shop is define to a group shop, disable the form if ($legacyContext->shop->getContext() == $shopContext->getShopContextGroupConstant()) { return $this->render('PrestaShopBundle:Admin/Product:formDisable.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); } $attributeGroups = $this->getDoctrine()->getManager()->getRepository('PrestaShopBundle:Attribute')->findByLangAndShop(1, 1); return array('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, 'preview_link' => $preview_url, 'preview_link_deactivate' => $preview_url_deactive, 'stats_link' => $legacyContextService->getAdminLink('AdminStats', true, ['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())); }