Spaces:
No application file
No application file
declare(strict_types=1); | |
namespace Mautic\LeadBundle\Field; | |
use Doctrine\DBAL\Exception\DriverException; | |
use Doctrine\DBAL\Schema\SchemaException as DoctrineSchemaException; | |
use Mautic\CoreBundle\Doctrine\Helper\IndexSchemaHelper; | |
use Mautic\CoreBundle\Exception\SchemaException; | |
use Mautic\LeadBundle\Entity\LeadField; | |
use Psr\Log\LoggerInterface; | |
class CustomFieldIndex | |
{ | |
public function __construct( | |
private IndexSchemaHelper $indexSchemaHelper, | |
private LoggerInterface $logger, | |
private FieldsWithUniqueIdentifier $fieldsWithUniqueIdentifier | |
) { | |
} | |
/** | |
* Update the unique_identifier_search index and add an index for this field. | |
* | |
* @throws DriverException | |
* @throws DoctrineSchemaException | |
* @throws SchemaException | |
*/ | |
public function addIndexOnColumn(LeadField $leadField): void | |
{ | |
try { | |
/** @var IndexSchemaHelper $modifySchema */ | |
$modifySchema = $this->indexSchemaHelper->setName($leadField->getCustomFieldObject()); | |
$alias = $leadField->getAlias(); | |
$modifySchema->addIndex([$alias], $alias.'_search'); | |
$modifySchema->allowColumn($alias); | |
$this->updateUniqueIdentifierIndex($leadField); | |
$modifySchema->executeChanges(); | |
} catch (DriverException $e) { | |
if (1069 === $e->getCode() /* ER_TOO_MANY_KEYS */) { | |
$this->logger->warning($e->getMessage()); | |
} else { | |
throw $e; | |
} | |
} | |
} | |
/** | |
* Updates the index for this field. | |
* | |
* @throws DriverException | |
* @throws DoctrineSchemaException | |
* @throws SchemaException | |
*/ | |
public function dropIndexOnColumn(LeadField $leadField): void | |
{ | |
try { | |
/** @var IndexSchemaHelper $modifySchema */ | |
$modifySchema = $this->indexSchemaHelper->setName($leadField->getCustomFieldObject()); | |
$alias = $leadField->getAlias(); | |
$modifySchema->dropIndex([$alias], $alias.'_search'); | |
$modifySchema->allowColumn($alias); | |
$modifySchema->executeChanges(); | |
} catch (DriverException $e) { | |
if (1069 === $e->getCode() /* ER_TOO_MANY_KEYS */) { | |
$this->logger->warning($e->getMessage()); | |
} else { | |
throw $e; | |
} | |
} | |
} | |
/** | |
* @throws SchemaException | |
*/ | |
public function isUpdatePending(LeadField $leadField): bool | |
{ | |
$hasIndex = $this->hasIndex($leadField); | |
if ($leadField->isIsIndex() !== $hasIndex) { | |
return true; | |
} | |
if (!$this->hasMatchingUniqueIdentifierIndex($leadField)) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* @throws SchemaException | |
*/ | |
public function hasIndex(LeadField $leadField): bool | |
{ | |
return $this->indexSchemaHelper->hasIndex($leadField); | |
} | |
public function hasMatchingUniqueIdentifierIndex(LeadField $leadField): bool | |
{ | |
$uniqueIdentifierColumns = $this->getUniqueIdentifierIndexColumns($leadField->getObject()); | |
try { | |
return $this->indexSchemaHelper->hasMatchingUniqueIdentifierIndex($leadField, $uniqueIdentifierColumns); | |
} catch (DoctrineSchemaException) { | |
// Return true only if there are no unique identifier fields but otherwise assume the index is missing | |
return 0 === count($uniqueIdentifierColumns); | |
} | |
} | |
/** | |
* @throws DoctrineSchemaException | |
* @throws SchemaException | |
*/ | |
public function updateUniqueIdentifierIndex(LeadField $leadField): void | |
{ | |
if ($this->hasMatchingUniqueIdentifierIndex($leadField)) { | |
return; | |
} | |
/** @var IndexSchemaHelper $modifySchema */ | |
$modifySchema = $this->indexSchemaHelper->setName($leadField->getCustomFieldObject()); | |
$indexColumns = $this->getUniqueIdentifierIndexColumns($leadField->getObject()); | |
if (!$indexColumns) { | |
$this->dropIndexForUniqueIdentifiers($leadField); | |
return; | |
} | |
$modifySchema->addIndex($indexColumns, 'unique_identifier_search'); | |
$modifySchema->executeChanges(); | |
} | |
/** | |
* @throws DoctrineSchemaException | |
* @throws SchemaException | |
*/ | |
private function dropIndexForUniqueIdentifiers(LeadField $leadField): void | |
{ | |
if (!$this->indexSchemaHelper->hasUniqueIdentifierIndex($leadField)) { | |
return; | |
} | |
/** @var IndexSchemaHelper $modifySchema */ | |
$modifySchema = $this->indexSchemaHelper->setName($leadField->getCustomFieldObject()); | |
$indexColumns = $this->getUniqueIdentifierIndexColumns($leadField->getObject()); | |
$modifySchema->dropIndex($indexColumns, 'unique_identifier_search'); | |
$modifySchema->executeChanges(); | |
} | |
/** | |
* @return array<mixed> | |
*/ | |
private function getUniqueIdentifierIndexColumns(string $object = 'lead'): array | |
{ | |
// Filters | |
$filters = ['object' => $object]; | |
// Get list of current uniques | |
$uniqueIdentifierFields = $this->fieldsWithUniqueIdentifier->getLiveFields($filters); | |
// Always use email | |
$indexColumns = array_keys($uniqueIdentifierFields); | |
// Only use three to prevent max key length errors | |
return array_slice($indexColumns, 0, 3); | |
} | |
} | |