formFactory = $formFactory; $this->latteEngine = $latteEngine; $this->carrierRepository = $carrierRepository; $this->carDeliveryConfig = $carDeliveryConfig; $this->productEntityFactory = $productEntityFactory; } /** * Register component. * * @return void */ public function register(): void { add_filter( 'woocommerce_product_data_tabs', [ $this, 'registerTab' ], 1, 1 ); add_action( 'woocommerce_product_data_panels', [ $this, 'render' ] ); add_action( 'woocommerce_process_product_meta', [ $this, 'saveData' ] ); } /** * Registers tab. * * @param string[] $tabs Tabs definition array. * * @return array|string> */ public function registerTab( array $tabs ): array { $tabs[ self::NAME ] = [ 'label' => __( 'Packeta', 'packeta' ), 'target' => self::NAME, 'class' => [ 'hide_if_virtual', 'hide_if_downloadable' ], ]; return $tabs; } /** * Creates form instance. * * @param Product\Entity $product Related product. * * @return Form */ private function createForm( Product\Entity $product ): Form { $form = $this->formFactory->create(); $form->addCheckbox( Product\Entity::META_AGE_VERIFICATION_18_PLUS, __( 'Age verification 18+', 'packeta' ) ); $carriersContainer = $form->addContainer( Product\Entity::META_DISALLOWED_SHIPPING_RATES ); $carriersList = $this->carrierRepository->getAllActiveCarriersList(); foreach ( $carriersList as $carrier ) { if ( $this->carDeliveryConfig->isCarDeliveryCarrierDisabled( OptionPrefixer::removePrefix( $carrier['option_id'] ) ) ) { continue; } $carriersContainer->addCheckbox( $carrier['option_id'], $carrier['label'] ); } $form->setDefaults( [ Product\Entity::META_AGE_VERIFICATION_18_PLUS => $product->isAgeVerificationRequired(), Product\Entity::META_DISALLOWED_SHIPPING_RATES => $product->getDisallowedShippingRateChoices(), ] ); return $form; } /** * Renders tab. * * @return void */ public function render(): void { $this->latteEngine->render( PACKETERY_PLUGIN_DIR . '/template/product/data-tab-panel.latte', [ 'form' => $this->createForm( $this->productEntityFactory->fromGlobals() ), 'translations' => [ 'disallowedShippingRatesHeading' => __( 'Packeta shipping methods disabled for this product.', 'packeta' ), ], ] ); } /** * Saves product data. * * @param int|string $postId Post ID. * * @throws ProductNotFoundException Product not found. */ public function saveData( $postId ): void { $product = $this->productEntityFactory->fromPostId( $postId ); if ( $product->isPhysical() === false ) { return; } $form = $this->createForm( $product ); $form->onSuccess[] = function ( Form $form, array $values ) use ( $product ) { $this->processFormData( $product->getId(), $values ); }; if ( $form->isSubmitted() ) { $form->fireEvents(); } } /** * Process form data. * * @param int $productId Product ID. * @param array> $values Form values. */ public function processFormData( int $productId, array $values ): void { foreach ( $values as $attr => $value ) { if ( is_bool( $value ) ) { $value = $value ? '1' : '0'; } if ( $attr === Product\Entity::META_DISALLOWED_SHIPPING_RATES ) { $value = array_filter( $value ); } update_post_meta( $productId, $attr, $value ); } } }