<?php
namespace App\EventSubscriber;
use Pimcore\Model\DataObject\Organization;
use Pimcore\Event\DataObjectEvents;
use Pimcore\Event\Model\DataObjectEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Pimcore\Model\DataObject\Organization\Listing;
class OrganizationUniqueIdSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
DataObjectEvents::PRE_ADD => 'onPreAdd',
DataObjectEvents::PRE_UPDATE => 'onPreAdd',
];
}
public function onPreAdd(DataObjectEvent $event): void
{
$object = $event->getObject();
if (!$object instanceof Organization || $object->getUniqueId()) {
return;
}
// Retry-safe loop
$maxRetries = 10;
$retryCount = 0;
do {
$nextNumber = $this->getNextUniqueNumber();
$newUniqueId = 'NCM-ENT-' . str_pad($nextNumber, 5, '0', STR_PAD_LEFT);
// Check uniqueness in DB
$existing = new Listing();
$existing->setCondition('uniqueId = ?', $newUniqueId);
if (count($existing) === 0) {
$object->setUniqueId($newUniqueId);
return;
}
$retryCount++;
} while ($retryCount < $maxRetries);
throw new \Exception('Unable to generate a unique ID for Organization after multiple attempts.');
}
private function getNextUniqueNumber(): int
{
$listing = new Listing();
$listing->setOrderKey('o_id');
$listing->setOrder('DESC');
$listing->setLimit(1);
$last = $listing->current();
$next = 1;
if ($last instanceof Organization) {
$lastId = $last->getUniqueId();
if (preg_match('/NCM-ENT-(\d+)/', $lastId, $matches)) {
$next = (int)$matches[1] + 1;
}
}
return $next;
}
}