Product Attribute: loyalty_points_multiplier am Produkt anlegen
Product Attribute: loyalty_points_multiplier am Produkt anlegen
~7 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026
Block 2 hat mit der Reward-Entity eine vollkommen neue EAV-Entität gebaut - eigene Tabellen, eigener Entity Type, eigenes Model/ResourceModel-Paar. Block 3 braucht nichts davon: catalog_product existiert längst als vollwertige EAV-Entität, komplett mit eav_entity_type-Eintrag, Attribut-Sets und den bekannten Wertetabellen catalog_product_entity_decimal & Co. Ein neues Produkt-Attribut ist deshalb ungleich einfacher als eine neue Entity: nur ein einziger Aufruf von EavSetup::addAttribute() auf einen bereits existierenden Entity-Type-Code.
Kein neuer Entity Type - nur ein Attribut
loyalty_points_multiplier (Typ decimal, Default 1.0) legt fest, mit welchem Faktor die Grundpunktzahl eines Produkts multipliziert wird - Kapitel 5 hat den Parameter $productMultiplier in PointsCalculator::calculatePoints() bereits genau für dieses Attribut vorgesehen. Ein Wert von 2.0 bedeutet "doppelte Punkte", ein Wert von 0.0 bedeutet "dieses Produkt bringt trotz Kauf keine Punkte".
<?php
declare(strict_types=1);
namespace Mironsoft\Loyalty\Setup\Patch\Data;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
/**
* Registers the loyalty_points_multiplier decimal attribute on catalog_product.
*/
class InstallProductLoyaltyAttribute implements DataPatchInterface
{
/**
* @param ModuleDataSetupInterface $moduleDataSetup Provides the setup connection for the patch.
* @param EavSetupFactory $eavSetupFactory Creates the EavSetup helper used to register the attribute.
*/
public function __construct(
private readonly ModuleDataSetupInterface $moduleDataSetup,
private readonly EavSetupFactory $eavSetupFactory
) {
}
/**
* Adds the loyalty_points_multiplier attribute to the existing catalog_product entity.
*
* @return void
*/
public function apply(): void
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var \Magento\Eav\Setup\EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(Product::ENTITY, 'loyalty_points_multiplier', [
'type' => 'decimal',
'label' => 'Loyalty Points Multiplier',
'input' => 'text',
'required' => false,
'default' => '1.0000',
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
'group' => 'General',
'sort_order' => 100,
'visible' => true,
'user_defined' => true,
'apply_to' => '',
'used_in_product_listing' => true,
]);
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* @return array<int, string>
*/
public static function getDependencies(): array
{
return [];
}
/**
* @return array<int, string>
*/
public function getAliases(): array
{
return [];
}
}Die wichtigsten Array-Schlüssel im Überblick
type- derbackend_type, bestimmt, in welche Wertetabelle (catalog_product_entity_decimal) der Wert geschrieben wird, exakt das Konzept aus Kapitel 14.apply_to- eine leere Zeichenkette bedeutet "für alle Produkttypen sichtbar"; eine kommagetrennte Liste wie'simple,virtual,configurable'würde das Attribut z. B. bei Gruppierten Produkten ausblenden.global- der Scope, hier bewusstSCOPE_GLOBALals Startpunkt; Kapitel 25 begründet, warum das für dieses konkrete Attribut später aufSCOPE_WEBSITEgeändert wird.used_in_product_listing- erlaubt dem Produkt-Collection-Loader im Frontend/Layer-Navigation-Kontext, den Wert ohne explizitenaddAttributeToSelect()-Aufruf performant mitzuladen.
Achtung: addAttribute() ordnet ein neues Attribut standardmäßig nur dem Attribut-Set Default zu. Existieren im Shop bereits weitere Attribut-Sets (z. B. für unterschiedliche Produktkategorien), taucht loyalty_points_multiplier dort nicht automatisch auf - das erfordert einen zusätzlichen Durchlauf über $eavSetup->getAllAttributeSetIds(Product::ENTITY) mit je einem addAttributeToSet()-Aufruf, oder eine manuelle Zuordnung im Admin unter Stores > Attribute Set.
Modul-Abhängigkeit Magento_Catalog ergänzen
catalog_product stammt aus Magento_Catalog - dieselbe Überlegung wie in Kapitel 2 (Magento_Customer, Magento_Sales) und Kapitel 11 (Magento_Eav) gilt auch hier: ohne sequence-Eintrag besteht keine Garantie, dass catalog_product beim Ausführen dieses Patches bereits existiert.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Mironsoft_Loyalty">
<sequence>
<module name="Magento_Customer"/>
<module name="Magento_Sales"/>
<module name="Magento_Eav"/>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>bin/magento setup:upgrade
bin/magento indexer:reindex catalog_product_attribute
bin/magento cache:flushTipp: Nach jedem neuen oder geänderten Katalog-Attribut lohnt ein gezielter Reindex von catalog_product_attribute statt eines vollständigen indexer:reindex - bei großen Katalogen ein spürbarer Zeitunterschied, und bin/cache-clean (CLAUDE.md) übernimmt anschließend den Hyvä-Watcher-Teil, falls Frontend-Templates ebenfalls betroffen sind.
Mit loyalty_points_multiplier am Produkt folgt Kapitel 20 demselben Muster für die Kategorie - mit einem wichtigen Unterschied beim Standard-Scope, den Kapitel 25 später aufgreift.