Skip to main content
Version: 2026.2

Customer Segments

Customer segmentation is the practice of dividing a customer base into groups of individuals that are similar in specific ways relevant to marketing, such as age, gender, interests, and spending habits.

CMF includes tools for creating and managing customer segments and segment groups. CustomerSegments and CustomerSegmentGroups are regular Pimcore objects, assigned to customer objects via relations.

Manual vs. Calculated Segments

The customer object has two separate object relation fields for manual and calculated segments. Add manual segments by drag and drop in Pimcore Studio. CMF adds calculated segments automatically during the segment building process.

manual vs calculated segmentsmanual vs calculated segmentsmanual vs calculated segments

Optional: Path Formatter for an Alternative Segment Display

custom path formattercustom path formattercustom path formatter

To use this compact segment relation presentation, add CustomerManagementFrameworkBundle\PathFormatter as the formatter class on the customer segment relation fields in the Pimcore class editor.

SegmentManager

The SegmentManager manages, creates, and reads CustomerSegments and CustomerSegmentGroups within CMF. See the SegmentManagerInterface for inline PHP docs on each method.

The SegmentManager is registered as CustomerManagementFrameworkBundle\SegmentManager\SegmentManagerInterface on the container. SegmentBuilders are an integral part of the SegmentManager: they do the actual work of calculating segments for a customer.

SegmentBuilders

Segment builders are PHP classes that implement SegmentBuilderInterface. Use them to create automatically calculated segments from customer data. For example, an "Age" SegmentBuilder could divide customers into age-group segments based on a birthday field.

Execute on Customer Save vs. Async

Implement a SegmentBuilder to run either directly on customer save or asynchronously via a cron job. Check the executeOnCustomerSave() method of SegmentBuilderInterface: if it returns true, the builder runs directly on customer save; otherwise, each customer change is added to a queue and processed later by a cron job.

SegmentManagerInterface has a method addCustomerToChangesQueue() to trigger customer changes. Call it every time a customer record or a SegmentBuilder-related data record changes. By default, this happens on customer object save and when a new customer activity is tracked. If your implementation has other events that should trigger segment building (for example, changes in objects related to a customer), call this method manually.

Create Your Own SegmentBuilder

Implement SegmentBuilderInterface. Most of the work happens in two methods: prepare(SegmentManagerInterface $segmentManager) and calculateSegments(CustomerInterface $customer, SegmentManagerInterface $segmentManager).

  • prepare() runs once when the SegmentBuilder is prepared, before calculateSegments() executes. Put one-time setup code here, such as initializations shared across all customers.
  • calculateSegments() does the actual work: it calculates the segment for the given customer and adds or removes the calculated segments according to your logic.

Both methods can call the SegmentManager to create segments and add or remove them from the customer.

SegmentManager sample calls:
<?php 
/* Create a segment called "male" within the segment group "gender". The segment group "gender" will be created too if
it doesn't exist.
If the segment already exists it will not be recreated but the existing segment will be returned.
*/
$segment = $segmentManager->createCalculatedSegment("male", "gender");

// Get all other segments of the segment group "gender" (but exclude "male")
$deleteSegments = $segmentManager->getSegmentsFromSegmentGroup($segment->getGroup(),[$segment]);

// Add the segment to the customer and remove all other segments from the segment group "gender").
// The param "GenderSegmentBuilder" is an optional comment which will be added to the notes/events tab of the customer.
$addSegments = [$segment];
$segmentManager->mergeSegments($customer, $addSegments, $deleteSegments, "GenderSegmentBuilder");
$segmentManager->saveMergedSegments($customer);
Optional: Store the Creation Date and Application Count of a Segment

CMF can handle potentially expiring segments by storing the creation date and a counter for how often a segment was added, if it applies multiple times. For example, a segment "interested in hiking" might need to expire or be removed after some time, and a counter is useful for tracking how often a customer performed an activity that led to that segment.

CMF supports both plain object relations and object relations with metadata to store a customer's manual and calculated segments. To use the creation date and counter feature, use an object relation with metadata for at least the calculatedSegments attribute, with these two metadata columns:

  • created_timestamp (type number)
  • application_counter (type number)

SegmentManager sample calls using the timestamp and counter storage features (see the PHPDoc on SegmentManagerInterface for more details):

<?php 
// Example last hiking/climbing activity timestamps (int values) calculated based on "hiking/climbing interest" activity data
$lastHikingActivityTimestamp;
$lastClimbingActivityTimestamp;

$hikingSegment = $segmentManager->createCalculatedSegment("interests", "hiking");
$climbingSegment = $segmentManager->createCalculatedSegment("interests", "climbing");

/*
Add the 2 segments with the given timestamps and let the counter increment automatically each time the timestamp changes.
The timestamp will be applied to all added segments in one mergeSegments call.
Therefore in this case 2 merge segment calls are needed as $hikingSegment and $climbingSegment should have different timestamps.
*/
$segmentManager->mergeSegments($customer, [$hikingSegment], [], "InterestSegmentBuilder", $lastHikingActivityTimestamp, true);
$segmentManager->mergeSegments($customer, [$climbingSegment], [], "InterestSegmentBuilder", $lastClimbingActivityTimestamp, true);
$segmentManager->saveMergedSegments($customer);

// The same example like above but manually determine the counter (based on activity data)
$hikingActivityCounter = 12;
$climbingActivityCounter = 3;

$segmentManager->mergeSegments($customer, [$hikingSegment], [], "InterestSegmentBuilder", $lastHikingActivityTimestamp, $hikingActivityCounter);
$segmentManager->mergeSegments($customer, [$climbingSegment], [], "InterestSegmentBuilder", $lastClimbingActivityTimestamp, $climbingActivityCounter);
$segmentManager->saveMergedSegments($customer);

Extract segment application counter of customers
<?php
// get all segment application counters of a customer
$all = $segmentManager->getSegmentExtractor()->getAllSegmentApplicationCounters($customer);
/*
example result (segmentId => application counter)
[
6692709 => 1,
6694297 => 1,
6697153=> 2
]
*/

// get segment application counter of a given segment
$count = $segmentManager->getSegmentExtractor()->getSegmentApplicationCounter($customer, $segment);

Registration of Segment Builders

Configure segment builders as services in the Symfony service container. Every service tagged cmf.segment_builder runs during the segment building process.

Example Service Definitions
services:
appbundle.cmf.segment_builder.state:
class: CustomerManagementFrameworkBundle\SegmentBuilder\StateSegmentBuilder
tags: [cmf.segment_builder]


appbundle.cmf.segment_builder.gender:
class: CustomerManagementFrameworkBundle\SegmentBuilder\GenderSegmentBuilder
arguments:
- 'Gender'
- 'male'
- 'female'
- 'gender unknown'

tags: [cmf.segment_builder]

Built-in Segment Builders

CMF includes the following SegmentBuilders out of the box.

AgeSegmentBuilder

Calculates age range segments based on a birthday field.

configuration optiondescription
segmentGroupname of the segment group
birthDayFieldname of the birthday field in the customer object
ageGroupsarray of arrays to define the used age groups. Example: [[0,50],[51,100]] would result in an age group 0-50 and another one with 51-100
GenderSegmentBuilder

Calculates segments based on the gender field.

configuration optiondescription
segmentGroupname of the segment group
maleSegmentNamename of the male segment
femaleSegmentNamename of the female segment
notsetSegmentNamename of the segment if the gender of the customer is not male or female
StateSegmentBuilder

Calculates state segments based on the zip field and zip ranges for each state. Currently works for AT, DE, and CH.

configuration optiondescription
segmentGroupname of the segment group
countryTransformersdata transformers used per country; each transformer converts the zip code to a state based on its own implementation

Console Commands

The following console commands support the segment building process.

Build Segments for Customers in the Changes Queue

Run this regularly, see also Cron Jobs:

bin/console cmf:build-segments

Build Segments for All Customers

bin/console cmf:build-segments -f

Build One Segment for All Customers

Provide the Symfony service ID of the SegmentBuilder:

bin/console cmf:build-segments --segmentBuilder='appbundle.cmf.segment_builder.state'

Segment Assignment to Pimcore Elements

Besides customers, you can also assign segments to other Pimcore elements, so elements like documents can be tagged with segments. Use this, for example, to track that a user visited several pages tagged with a certain segment. See the Segment Assignment chapter for details.