Mappings
Accessing and querying Siren mappings — the bridge between Siren entity IDs and external platform IDs — through the PHP data layer.
Last updated: April 8, 2026
Mappings
A mapping in Siren links a local Siren entity to an entity in an external system. Every time Siren needs to know “which WooCommerce order does this conversion correspond to?” or “which Stripe customer is this collaborator?”, it looks up a mapping. The mapping table stores these relationships as pairs of IDs qualified by type strings, so the same table can bridge any combination of local and external resources.
Mappings are one of the most integration-critical datastores in Siren. If you’re building a custom integration with a payment gateway, CRM, or e-commerce platform, you’ll use mappings to track which records on each side correspond to each other. Unlike most other Siren datastores, mappings use a compound key (the combination of localId, externalId, localType, and externalType) rather than a single auto-incrementing primary key.
Siren is built on an event-driven architecture. Siren’s built-in integrations (WooCommerce, EDD, LifterLMS, etc.) create mappings automatically as part of their event handlers. If you’re building a custom integration, you’ll create mappings in your own event handlers. This typically happens when processing an inbound webhook or synchronizing records.
Accessing mapping data
The mapping datastore is available through dependency injection or the static facade.
use Siren\Mappings\Core\Datastores\Mapping\Interfaces\MappingDatastore;
class OrderSync
{
protected MappingDatastore $mappings;
public function __construct(MappingDatastore $mappings)
{
$this->mappings = $mappings;
}
public function getSirenConversionForOrder(int $wcOrderId): ?\Siren\Mappings\Core\Models\Mapping
{
try {
return $this->mappings->getByExternalId($wcOrderId, 'wc_order', 'conversion');
} catch (\PHPNomad\Datastore\Exceptions\RecordNotFoundException $e) {
return null;
}
}
} use Siren\Mappings\Core\Facades\Mappings;
try {
$mapping = Mappings::getByExternalId($wcOrderId, 'wc_order', 'conversion');
$conversionId = $mapping->getLocalId();
} catch (\PHPNomad\Datastore\Exceptions\RecordNotFoundException $e) {
// This order hasn't been processed by Siren yet
} The mapping model
Each mapping record is represented by a Mapping model instance.
| Field | Type | Description |
|---|---|---|
localId | int | The ID of the Siren entity |
externalId | int or string | The ID from the external system |
localType | string | What kind of Siren entity this is (e.g., conversion, collaborator, transaction) |
externalType | string | What kind of external entity this is (e.g., wc_order, stripe_customer, edd_payment) |
Getter methods: getLocalId(), getExternalId(), getLocalType(), getExternalType().
The identity of a mapping is the full compound key. All four fields together form the identity. There is no single id column. The getIdentity() method returns an array with all four fields.
Available methods
The mapping datastore provides the standard CRUD methods documented in the introduction. It adds several domain-specific methods designed for the common lookup patterns integrations need.
Finding a specific mapping
find retrieves a single mapping by all four compound key fields. This is the most precise lookup. Use it when you know both the local and external identifiers and need to confirm the mapping exists. This method is available on the datastore interface through dependency injection.
use Siren\Mappings\Core\Datastores\Mapping\Interfaces\MappingDatastore;
// Inside a service class with MappingDatastore injected
try {
$mapping = $this->mappings->find(42, 'conversion', 1001, 'wc_order');
// The mapping exists -- this WC order is already linked to this conversion
} catch (\PHPNomad\Datastore\Exceptions\RecordNotFoundException $e) {
// No mapping exists for this combination
}
Looking up by local ID
getByLocalId finds the mapping for a Siren entity when you need to discover which external record it corresponds to. You provide the local ID, local type, and the external type you’re looking for.
use Siren\Mappings\Core\Facades\Mappings;
// Find the WooCommerce product linked to a Siren collaborator coupon
try {
$mapping = Mappings::getByLocalId($collaboratorId, 'collaborator', 'wc_coupon');
$wcCouponId = $mapping->getExternalId();
} catch (\PHPNomad\Datastore\Exceptions\RecordNotFoundException $e) {
// This collaborator doesn't have a WC coupon mapped
}
Looking up by external ID
getByExternalId is the reverse lookup. You have an external system’s ID and need to find the corresponding Siren entity. This is the most common lookup in inbound webhook handlers.
use Siren\Mappings\Core\Facades\Mappings;
// When processing an incoming WooCommerce order webhook,
// check if this order has already been processed
try {
$mapping = Mappings::getByExternalId($wcOrderId, 'wc_order', 'conversion');
// Already processed -- the conversion ID is $mapping->getLocalId()
} catch (\PHPNomad\Datastore\Exceptions\RecordNotFoundException $e) {
// New order -- process it and create the mapping
}
Deleting mappings for a local entity
deleteMappingsForLocalId removes all mappings for a given local entity, regardless of which external systems they point to. This is useful during cleanup or when a Siren entity is being removed.
use Siren\Mappings\Core\Facades\Mappings;
// Remove all external mappings for a collaborator
Mappings::deleteMappingsForLocalId($collaboratorId, 'collaborator');
Deleting mappings for an external entity
deleteMappingsForExternalId removes all mappings pointing to a specific external entity. Use this when the external record is being deleted or when you need to unlink an external resource from Siren.
use Siren\Mappings\Core\Facades\Mappings;
// Unlink a WooCommerce coupon from all Siren entities
Mappings::deleteMappingsForExternalId($wcCouponId, 'wc_coupon');
Deleting a specific mapping
delete removes a single mapping identified by all four compound key fields. Unlike deleteMappingsForLocalId and deleteMappingsForExternalId, this targets exactly one relationship. This method is available on the datastore interface through dependency injection.
use Siren\Mappings\Core\Datastores\Mapping\Interfaces\MappingDatastore;
// Inside a service class with MappingDatastore injected
$this->mappings->delete(42, 'conversion', 1001, 'wc_order');
Practical patterns
Checking if an order has been processed
The most common integration pattern is checking whether an inbound event has already been handled. Before creating a new conversion from a WooCommerce order, check whether a mapping already exists.
use Siren\Mappings\Core\Facades\Mappings;
function hasOrderBeenProcessed(int $wcOrderId): bool
{
try {
Mappings::getByExternalId($wcOrderId, 'wc_order', 'conversion');
return true;
} catch (\PHPNomad\Datastore\Exceptions\RecordNotFoundException $e) {
return false;
}
}
Linking a WooCommerce product to a collaborator
When building custom integration logic that needs to associate external platform records with Siren entities, create a mapping to track the relationship.
use Siren\Mappings\Core\Facades\Mappings;
// After creating a WooCommerce coupon for a collaborator,
// store the mapping so Siren can resolve it later
Mappings::create([
'localId' => $collaboratorId,
'localType' => 'collaborator',
'externalId' => $wcCouponId,
'externalType' => 'wc_coupon'
]);