Customer Save Manager
The customer save manager is responsible for all actions and hooks executed when a customer object is saved. It consists of several parts.
Customer Save Handlers
Customer save handlers are PHP classes executed when a customer is saved. Use them to normalize, validate, optimize, or modify customers on save.
Register customer save handlers as Symfony services tagged cmf.customer_save_handler, so a project can add multiple
handlers. Implement the
CustomerSaveHandlerInterface,
which declares a method for each Pimcore object event (preAdd, postAdd, preUpdate, etc.).
A customer save handler can also fetch the original customer object from the database, which is useful for comparing whether a field changed.
Example service definition
services:
appbundle.cmf.customer_save_handler.normalize_zip:
class: CustomerManagementFrameworkBundle\CustomerSaveHandler\NormalizeZip
tags: [cmf.customer_save_handler]
Built-in Customer Save Handlers
CMF ships with the following customer save handlers, all in the CustomerManagementFrameworkBundle\CustomerSaveHandler
namespace. Enable one by adding a corresponding service tagged cmf.customer_save_handler to the container. Check
each handler's constructor for its configuration options.
Cleanup\Email
Removes invalid characters from an email field.
NormalizeZip
Normalizes zip codes; for example, A-1010 becomes 1010. It ships with zip correction regexes for several
countries, and the logic can be extended for others.
SalutationToGender
Maps a salutation field to a gender field. This can automatically adjust the gender based on the salutation.
RemoveBlacklistedEmails
Sets the email field to an empty value if the given email address is in a defined blacklist.
MarkEmailAddressAsValid
Marks an email address as valid if it has a valid format. Marking as valid means that a special checkbox get checked.
AttributeLogic
Allows to setup a logic for overwriting field values based on other field values.
Example:
appbundle.cmf.customer_save_handler.attribute_logic:
class: CustomerManagementFrameworkBundle\CustomerSaveHandler\AttributeLogic
arguments:
- from: profileStreet
to: street
overwriteIfNotEmpty: true
- from: profileZip
to: zip
overwriteIfNotEmpty: true
In this example "street" will be overwritten if "profileStreet" changes (the same for zip and profileZip).
If overwriteIfNotEmpty is set to false the to field will be overwritten only when it's empty.
Important: the to-field's value is overwritten only if the from-field changed during the current save process and the to-field's value did not change.
Automatic Object Naming Scheme
CMF can automatically apply a naming scheme to customer objects based on configured logic. Disable this automatic naming scheme if you do not need it.
Example Configuration
pimcore_customer_management_framework:
customer_save_manager:
enableAutomaticObjectNamingScheme: true
customer_provider:
parentPath: /customers
archiveDir: /customers/_archive
namingScheme: '{countryCode}/{zip}/{firstname}-{lastname}'
With this configuration, CMF automatically saves every customer object under /customers, in subfolders starting
with the customer's countryCode, then the zip code as the second level, and gives the object itself a key of
{firstname}-{lastname}. CMF adds a postfix automatically if a customer object with the same key already exists in
that folder.
Configure two customer folders: parentPath for regular customers, and archiveDir for customers who are
unpublished and inactive.
Customer Save Validator
When enabled, the customer save validator throws an exception if the customer is invalid according to its implementation. Catch these exceptions in a try/catch block to check whether a customer is valid. In Pimcore Studio, an error message alerts the user when they try to save an invalid customer.
Example configuration
pimcore_customer_management_framework:
customer_save_validator:
checkForDuplicates: true
requiredFields:
- [email],
- [firstname, name, zip]
customer_duplicates_services:
duplicateCheckFields:
- [email]
- [firstname, lastname, zip, street]
This example validates a customer on save in two ways:
-
First, it checks whether either the
emailfield or thefirstname+name+zipcombination is filled in. Define as many field combinations as needed. -
Second, CMF also searches for duplicate customers and declines the save if a duplicate exists. Configure the field combinations checked for duplicates independently.
Save Customer with Disabled Hooks
In most cases it's sufficient to just call $customer->save() to save a customer object.
Sometimes it's needed to save a customer without validation or without applying for example customer save handlers or
segment builders.
The CMF offers a special SaveOptions class to handle the enabled state of all hooks when a customer gets saved.
Caution: only disable parts of the save options if you are sure that it is needed!
Examples
<?php
$customer = Customer::getById(1234);
// Disable all hooks and also Pimcore versioning.
$customer->saveDirty();
// Disable all hooks but enable Pimcore versioning.
$customer->saveDirty(false);
// Globally disable on save segment building and also the segment builder queue
$customer->getSaveManager()->getSaveOptions()
->disableOnSaveSegmentBuilders()
->disableSegmentBuilderQueue();
// Save customer with disabled object naming scheme but let the global state untouched
// (`getSaveOptions(true)` will deliver a cloned instance of the save options)
$saveOptions = $customer->getSaveManager()->getSaveOptions(true)
->disableObjectNamingScheme();
$customer->saveWithOptions($saveOptions);
// Save customer with enabled object naming scheme even if it is disabled by default in the config
$saveOptions = $customer->getSaveManager()->getSaveOptions(true)
->enableObjectNamingScheme();
$customer->saveWithOptions($saveOptions);