system.xml file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="specials_subcategory" translate="label" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<class>separator-top</class>
<label>Category Specials</label>
<tab>ThreeYearOrders</tab>
<resource>Gelmar_SpecialsSubCategory::config</resource>
<group id="general" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Settings</label>
<field id="run_specials_logic" translate="label" type="button" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Update Category Specials</label>
<button class="action specials" type="button">
<span>Update</span>
</button>
<action>
<url path="gelmar/specials/run" />
</action>
</field>
</group>
</section>
</system>
</config>
This is my system.xml file. The settings label and button both display but the button has no text. I simply just want the button to say “Update”. Please advise or give suggestions.
Next I need help with my functionality. Below I have my Run.php file which is supposed to add the corresponding category ID to the product if it is in the specials category. So for example if I have a product that is in my Bathroom category and is on special it should add to the Bathroom specials category. I have double checked the IDs and they are all correct however it does not seem to be working.
Run.php file
<?php
namespace GelmarSpecialsSubCategoryControllerAdminhtmlSpecials;
use MagentoBackendAppAction;
use MagentoCatalogModelResourceModelProductCollectionFactory as ProductCollectionFactory;
use MagentoCatalogApiCategoryLinkManagementInterface;
use MagentoFrameworkControllerResultFactory;
class Run extends Action
{
protected $productCollectionFactory;
protected $categoryLinkManagement;
public function __construct(
ActionContext $context,
ProductCollectionFactory $productCollectionFactory,
CategoryLinkManagementInterface $categoryLinkManagement
) {
parent::__construct($context);
$this->productCollectionFactory = $productCollectionFactory;
$this->categoryLinkManagement = $categoryLinkManagement;
}
public function execute()
{
// Category IDs
$specialsCategoryId = 206;
$mapping = [
249 => 259,
5 => 260,
21 => 261,
19 => 262,
24 => 263,
28 => 264,
53 => 265
];
// Get all products in the Specials category (206)
$productCollection = $this->productCollectionFactory->create()
->addCategoriesFilter(['in' => $specialsCategoryId]);
// Consider adding pagination or limiting the collection size
// $productCollection->setPageSize(100)->setCurPage(1);
// Loop through the products
foreach ($productCollection as $product) {
$categoryIds = $product->getCategoryIds();
// Use array_intersect() for better performance
$categoriesToAdd = array_intersect(array_keys($mapping), $categoryIds);
$newCategoryIds = array_merge($categoryIds, array_map(function($id) use ($mapping) {
return $mapping[$id];
}, $categoriesToAdd));
// Ensure no duplicates
$newCategoryIds = array_unique($newCategoryIds);
// Only update if categories have changed
if ($newCategoryIds !== $categoryIds) {
try {
$this->categoryLinkManagement->assignProductToCategories($product->getSku(), $newCategoryIds);
} catch (Exception $e) {
// Log the error or handle it as needed
$this->messageManager->addErrorMessage(__('Error assigning categories to product %1: %2', $product->getSku(), $e->getMessage()));
}
}
}
// Display success message in the admin
$this->messageManager->addSuccessMessage(__('Specials category update completed successfully.'));
// Redirect back to the config page
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('adminhtml/system_config/edit/section/specials_subcategory');
return $resultRedirect;
}
}
I am not sure if my Run.php file is incorrect or if my system.xml file is incorrect. Basically what I want to happen is to be able to click a button on the admin side and then it updates the products that are on special to add the necessary category IDs such as Bathroom specials and then has a message to say all products have been updated. Please advise and give suggestions