0

I'm new to Magento 2 and to this forum. I'm trying to add a newsletter subscription on the customer menu, just after the core one.

For that, i created a module "ACME_Newsletter"

  1. I added a custom field to the customer_entity table via a db_schema :

     <table name="customer_entity"> <column xsi:type="boolean" name="acme_nl_subscription" nullable="false" default="false" comment="Acme Newsletter Subscription" /> 
  2. I created a layout that completes the existing one "customer_newsletter"

 <body> <referenceBlock name="customer_newsletter"> <container name="customer.form.newsletter.extra"> <block class="ACME\Newsletter\Block\Subscription" name="customer_form_newsletter_extra" as="acme_nl_subscription" template="ACME_Newsletter::customer/form/subscription.phtml" /> </container> </referenceBlock> </body> 

Here is my template :

 <?php /** @var \ACME\Newsletter\Block\Subscription $block */ ?> <?= $block->getChildHtml('customer.form.newsletter.extra') ?> <div class="field choice"> <input type="checkbox" name="acme_nl_subscription" id="acme_nl_subscription" value="1" title="<?= $block->escapeHtmlAttr(__('ACME\'s Newsletter Subscription')) ?>" <?php if ($block->getCustomerSession()->getCustomer()->getAcmeNlSubscription()) : ?> checked="checked"<?php endif; ?> class="checkbox"> <label for="acme_nl_subscription" class="label"><span><?= $block->escapeHtml(__('ACME\'s Newsletter Subscription')) ?></span></label> </div> 

And my block :

 <?php namespace ACME\Newsletter\Block; use Magento\Customer\Block\Newsletter; class Subscription extends Newsletter { public function getCustomerSession() { return $this->customerSession; } } 

With all that I manage to retrieve the value stored in database.

Now I try to modify that value and to store it in db, within an after plugin on the Magento\Newsletter\Controller\Manage\Save::execute() method.

I can't find the right way to write my method to persist this data. For the moment, my plugin looks like this :

<?php namespace ACME\Newsletter\Plugin; use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Model\Session; use Magento\Newsletter\Controller\Manage\Save; use Magento\Framework\App\RequestInterface; use Magento\Customer\Model\ResourceModel\CustomerRepository as CustomerRepository; use Magento\Customer\Model\ResourceModel\Customer as CustomerResource; use Magento\Customer\Model\Customer as CustomerModel; class AfterSavePlugin { protected $customerSession; protected $request; protected $customerRepository; protected $customerRepositoryInterface; protected $customerResource; protected $customerModel; public function __construct( Session $customerSession, RequestInterface $request, CustomerRepositoryInterface $customerRepositoryInterface, CustomerRepository $customerRepository, CustomerResource $customerResource, CustomerModel $customerModel ) { $this->customerSession = $customerSession; $this->request = $request; $this->customerRepository = $customerRepository; $this->customerRepositoryInterface = $customerRepositoryInterface; $this->customerResource = $customerResource; $this->customerModel = $customerModel; } public function afterExecute(Save $subject, $result) { $acmeNlSubscription = $this->request->getParam('acme_nl_subscription') ? (bool)$this->request->getParam('acme_nl_subscription') : 0; $sessionCustomer = $this->customerSession->getCustomer(); $customerData = $sessionCustomer->getData(); $repositoryCustomer = $this->customerRepository->getById($sessionCustomer->getId()); // $modelCustomer->loadByEmail($sessionCustomer->getEmail()); $modelCustomer = $this->customerModel; $modelCustomer->setData($customerData); $resourceCustomer = $this->customerResource->loadByEmail($modelCustomer, $modelCustomer->getEmail()); $modelCustomer->save(); return $result; } } 

Could a kind soul help me to take a step in my understanding of Adobe Commerce 2 (Magento 2) please?

What am I doing wrong? All comments are welcome, thank you!


Thank you for your help, but it didn't help me to resolve my problem yet.

I tried that too :

public function afterExecute(Save $subject, $result) { $acmeNlSubscription = $this->request->getParam('acme_nl_subscription') ? (int)$this->request->getParam('acme_nl_subscription') : 0; $customerId = $this->customerSession->getCustomerId(); $customer = $this->customerRepositoryInterface->getById($customerId); $customer->setData('acme_nl_subscription', $acmeNlSubscription); $this->customerRepositoryInterface->save($customer); return $result; } 

I can't understand why that doesn't work ???

2 Answers 2

0

Try adding before:

$modelCustomer->save(); 

The following line:

$modelCustomer->setAcmeNlSubscription($acmeNlSubscription); 
1
  • Thank you for your help @Sundar. I finally found a solution that I'm posting next. Commented May 10, 2023 at 9:01
0

I finally found a solution by adding a Data Patch

<?php namespace ACME\Newsletter\Setup\Patch\Data; use Magento\Customer\Model\Customer; use Magento\Customer\Setup\CustomerSetup; use Magento\Customer\Setup\CustomerSetupFactory; use Magento\Eav\Model\Entity\Attribute\Set; use Magento\Eav\Model\Entity\Attribute\SetFactory; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\Setup\Patch\PatchRevertableInterface; class AddSubscriptionColumn implements DataPatchInterface, PatchRevertableInterface { /** * @var ModuleDataSetupInterface */ private $moduleDataSetup; /** * @var SetFactory */ private $attributeSetFactory; /** * @var CustomerSetup */ private $customerSetupFactory; /** * Constructor * * @param ModuleDataSetupInterface $moduleDataSetup * @param SetFactory $attributeSetFactory * @param CustomerSetupFactory $customerSetupFactory */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, SetFactory $attributeSetFactory, CustomerSetupFactory $customerSetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->attributeSetFactory = $attributeSetFactory; $this->customerSetupFactory = $customerSetupFactory; } /** * {@inheritdoc} */ public function apply() { $this->moduleDataSetup->getConnection()->startSetup(); /** @var CustomerSetup $setupCustomer */ $setupCustomer = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]); $customerEntity = $setupCustomer->getEavConfig()->getEntityType(Customer::ENTITY); $defaultAttributeSetId = $customerEntity->getDefaultAttributeSetId(); /** @var $attributeSet Set */ $attributeSet = $this->attributeSetFactory->create(); $attributeGroupId = $attributeSet->getDefaultGroupId($defaultAttributeSetId); $setupCustomer->addAttribute( Customer::ENTITY, 'acme_nl_subscription', [ 'type' => 'static', 'label' => 'Acme Newsletter Subscription', 'input' => 'text', 'required' => false, 'visible' => true, 'user_defined' => true, 'sort_order' => 1000, 'position' => 1000, 'system' => 0, ] ); $attribute = $setupCustomer->getEavConfig()->getAttribute(Customer::ENTITY, 'acme_nl_subscription'); $attribute->addData([ 'used_in_forms' => [ 'adminhtml_customer', 'adminhtml_checkout', 'checkout_register', 'customer_account_create', 'newsletter_manage', 'newsletter_manage_save' ] ]); $attribute->addData([ 'attribute_set_id' => $defaultAttributeSetId, 'attribute_group_id' => $attributeGroupId ]); $attribute->save(); $this->moduleDataSetup->getConnection()->endSetup(); } /** * Rollback all changes * * @return void */ public function revert() { $this->moduleDataSetup->getConnection()->startSetup(); /** @var CustomerSetup $setupCustomer */ $setupCustomer = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]); $setupCustomer->removeAttribute(Customer::ENTITY, 'acme_nl_subscription'); $this->moduleDataSetup->getConnection()->endSetup(); } /** * {@inheritdoc} */ public function getAliases() { return []; } /** * {@inheritdoc} */ public static function getDependencies() { return []; } } 

The latest version of my method AfterSavePlugin::afterExecute()

 public function afterExecute(Save $subject, $result) { try { $acmeNlSubscription = $subject->getRequest()->getParam('acme_nl_subscription') ? $subject->getRequest()->getParam('acme_nl_subscription') : 0; $customerId = $this->customerSession->getCustomerId(); $customer = $this->customerFactory->create()->load($customerId); $customer->setAcmeNlSubscription($acmeNlSubscription); $this->customerRepository->save($customer->getDataModel()); } catch (Exception $exception) { $this->logger->error($exception->getMessage()); } return $result; } 

If anyone can explain to me why this is necessary to create a Data Patch, I'm interested! Feel free to comment or suggest a better solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.