Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\PluginBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\CoreBundle\Entity\CacheInvalidateInterface;
|
||||
use Mautic\CoreBundle\Entity\CommonEntity;
|
||||
|
||||
class Integration extends CommonEntity implements CacheInvalidateInterface
|
||||
{
|
||||
public const CACHE_NAMESPACE = 'IntegrationSettings';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var Plugin|null
|
||||
*/
|
||||
private $plugin;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isPublished = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $supportedFeatures = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $apiKeys = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $featureSettings = [];
|
||||
|
||||
public static function loadMetadata(ORM\ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable('plugin_integration_settings')
|
||||
->setCustomRepositoryClass(IntegrationRepository::class);
|
||||
|
||||
$builder->createField('id', 'integer')
|
||||
->makePrimaryKey()
|
||||
->generatedValue()
|
||||
->build();
|
||||
|
||||
$builder->createManyToOne('plugin', 'Plugin')
|
||||
->inversedBy('integrations')
|
||||
->addJoinColumn('plugin_id', 'id', true, false, 'CASCADE')
|
||||
->build();
|
||||
|
||||
$builder->addField('name', 'string');
|
||||
|
||||
$builder->createField('isPublished', 'boolean')
|
||||
->columnName('is_published')
|
||||
->build();
|
||||
|
||||
$builder->createField('supportedFeatures', 'array')
|
||||
->columnName('supported_features')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('apiKeys', 'array')
|
||||
->columnName('api_keys')
|
||||
->build();
|
||||
|
||||
$builder->createField('featureSettings', 'array')
|
||||
->columnName('feature_settings')
|
||||
->nullable()
|
||||
->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Plugin|null
|
||||
*/
|
||||
public function getPlugin()
|
||||
{
|
||||
return $this->plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $plugin
|
||||
*
|
||||
* @return Integration
|
||||
*/
|
||||
public function setPlugin($plugin)
|
||||
{
|
||||
$this->plugin = $plugin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $name
|
||||
*
|
||||
* @return Integration
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->isChanged('name', $name);
|
||||
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIsPublished()
|
||||
{
|
||||
return $this->isPublished;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $isPublished
|
||||
*
|
||||
* @return Integration
|
||||
*/
|
||||
public function setIsPublished($isPublished)
|
||||
{
|
||||
$this->isChanged('isPublished', $isPublished);
|
||||
|
||||
$this->isPublished = $isPublished;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isPublished(): bool
|
||||
{
|
||||
return $this->isPublished;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSupportedFeatures()
|
||||
{
|
||||
return $this->supportedFeatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $supportedFeatures
|
||||
*
|
||||
* @return Integration
|
||||
*/
|
||||
public function setSupportedFeatures($supportedFeatures)
|
||||
{
|
||||
$this->isChanged('supportedFeatures', $supportedFeatures);
|
||||
|
||||
$this->supportedFeatures = $supportedFeatures;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getApiKeys()
|
||||
{
|
||||
return $this->apiKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $apiKeys
|
||||
*
|
||||
* @return Integration
|
||||
*/
|
||||
public function setApiKeys($apiKeys)
|
||||
{
|
||||
$this->apiKeys = $apiKeys;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFeatureSettings()
|
||||
{
|
||||
return $this->featureSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $featureSettings
|
||||
*
|
||||
* @return Integration
|
||||
*/
|
||||
public function setFeatureSettings($featureSettings)
|
||||
{
|
||||
$this->isChanged('featureSettings', $featureSettings);
|
||||
|
||||
$this->featureSettings = $featureSettings;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCacheNamespacesToDelete(): array
|
||||
{
|
||||
return [self::CACHE_NAMESPACE];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\PluginBundle\Entity;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\CoreBundle\Entity\CommonEntity;
|
||||
|
||||
class IntegrationEntity extends CommonEntity
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $integration;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $integrationEntity;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $integrationEntityId;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
*/
|
||||
private $dateAdded;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
*/
|
||||
private $lastSyncDate;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $internalEntity;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $internalEntityId;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $internal;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->internal = new ArrayCollection();
|
||||
}
|
||||
|
||||
public static function loadMetadata(ORM\ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable('integration_entity')
|
||||
->setCustomRepositoryClass(IntegrationEntityRepository::class)
|
||||
->addIndex(['integration', 'integration_entity', 'integration_entity_id'], 'integration_external_entity')
|
||||
->addIndex(['integration', 'internal_entity', 'internal_entity_id'], 'integration_internal_entity')
|
||||
->addIndex(['integration', 'internal_entity', 'integration_entity'], 'integration_entity_match')
|
||||
->addIndex(['integration', 'last_sync_date'], 'integration_last_sync_date')
|
||||
->addIndex(['internal_entity_id', 'integration_entity_id', 'internal_entity', 'integration_entity'], 'internal_integration_entity');
|
||||
|
||||
$builder->addId();
|
||||
|
||||
$builder->addDateAdded();
|
||||
|
||||
$builder->addNullableField('integration', 'string');
|
||||
|
||||
$builder->createField('integrationEntity', 'string')
|
||||
->columnName('integration_entity')
|
||||
->nullable()
|
||||
->build();
|
||||
$builder->createField('integrationEntityId', 'string')
|
||||
->columnName('integration_entity_id')
|
||||
->nullable()
|
||||
->build();
|
||||
$builder->createField('internalEntity', 'string')
|
||||
->columnName('internal_entity')
|
||||
->nullable()
|
||||
->build();
|
||||
$builder->createField('internalEntityId', 'integer')
|
||||
->columnName('internal_entity_id')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('lastSyncDate', 'datetime')
|
||||
->columnName('last_sync_date')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->addNullableField('internal', 'array');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIntegration()
|
||||
{
|
||||
return $this->integration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $integration
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setIntegration($integration)
|
||||
{
|
||||
$this->integration = $integration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIntegrationEntity()
|
||||
{
|
||||
return $this->integrationEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $integrationEntity
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setIntegrationEntity($integrationEntity)
|
||||
{
|
||||
$this->integrationEntity = $integrationEntity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIntegrationEntityId()
|
||||
{
|
||||
return $this->integrationEntityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $integrationEntityId
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setIntegrationEntityId($integrationEntityId)
|
||||
{
|
||||
$this->integrationEntityId = $integrationEntityId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getDateAdded()
|
||||
{
|
||||
return $this->dateAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $dateAdded
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setDateAdded($dateAdded)
|
||||
{
|
||||
$this->dateAdded = $dateAdded;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getLastSyncDate()
|
||||
{
|
||||
return $this->lastSyncDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $lastSyncDate
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setLastSyncDate($lastSyncDate)
|
||||
{
|
||||
$this->lastSyncDate = $lastSyncDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInternalEntity()
|
||||
{
|
||||
return $this->internalEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $internalEntity
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setInternalEntity($internalEntity)
|
||||
{
|
||||
$this->internalEntity = $internalEntity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getInternalEntityId()
|
||||
{
|
||||
return $this->internalEntityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $internalEntityId
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setInternalEntityId($internalEntityId)
|
||||
{
|
||||
$this->internalEntityId = $internalEntityId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getInternal()
|
||||
{
|
||||
return $this->internal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $internal
|
||||
*
|
||||
* @return IntegrationEntity
|
||||
*/
|
||||
public function setInternal($internal)
|
||||
{
|
||||
$this->internal = $internal;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\PluginBundle\Entity;
|
||||
|
||||
use Doctrine\DBAL\ArrayParameterType;
|
||||
use Doctrine\DBAL\Query\Expression\CompositeExpression;
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<IntegrationEntity>
|
||||
*/
|
||||
class IntegrationEntityRepository extends CommonRepository
|
||||
{
|
||||
/**
|
||||
* @param array<int>|int|null $internalEntityIds
|
||||
* @param mixed $startDate
|
||||
* @param mixed $endDate
|
||||
* @param bool $push
|
||||
* @param int $start
|
||||
* @param int $limit
|
||||
* @param int|string|array<int|string>|null $integrationEntityIds
|
||||
*/
|
||||
public function getIntegrationsEntityId(
|
||||
$integration,
|
||||
$integrationEntity,
|
||||
$internalEntity,
|
||||
$internalEntityIds = null,
|
||||
$startDate = null,
|
||||
$endDate = null,
|
||||
$push = false,
|
||||
$start = 0,
|
||||
$limit = 0,
|
||||
$integrationEntityIds = null,
|
||||
): array {
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->select('DISTINCT(i.integration_entity_id), i.id, i.internal_entity_id, i.integration_entity, i.internal_entity')
|
||||
->from(MAUTIC_TABLE_PREFIX.'integration_entity', 'i');
|
||||
|
||||
$q->where('i.integration = :integration')
|
||||
->andWhere('i.internal_entity = :internalEntity')
|
||||
->setParameter('integration', $integration)
|
||||
->setParameter('internalEntity', $internalEntity);
|
||||
|
||||
if ($integrationEntity) {
|
||||
$q->andWhere('i.integration_entity = :integrationEntity')
|
||||
->setParameter('integrationEntity', $integrationEntity);
|
||||
}
|
||||
|
||||
if ('lead' === $internalEntity) {
|
||||
$joinCondition = $q->expr()->and(
|
||||
$q->expr()->eq('l.id', 'i.internal_entity_id')
|
||||
);
|
||||
|
||||
if ($push) {
|
||||
$joinCondition->with(
|
||||
$q->expr()->gte('l.last_active', ':startDate')
|
||||
);
|
||||
$q->setParameter('startDate', $startDate);
|
||||
}
|
||||
|
||||
$q->join('i', MAUTIC_TABLE_PREFIX.'leads', 'l', $joinCondition);
|
||||
}
|
||||
|
||||
if ($internalEntityIds) {
|
||||
if (is_array($internalEntityIds)) {
|
||||
$q->andWhere('i.internal_entity_id in (:internalEntityIds)')
|
||||
->setParameter('internalEntityIds', $internalEntityIds, ArrayParameterType::STRING);
|
||||
} else {
|
||||
$q->andWhere('i.internal_entity_id = :internalEntityId')
|
||||
->setParameter('internalEntityId', $internalEntityIds);
|
||||
}
|
||||
}
|
||||
|
||||
if ($startDate and !$push) {
|
||||
$q->andWhere('i.last_sync_date >= :startDate')
|
||||
->setParameter('startDate', $startDate);
|
||||
}
|
||||
|
||||
if ($endDate and !$push) {
|
||||
$q->andWhere('i.last_sync_date <= :endDate')
|
||||
->setParameter('endDate', $endDate);
|
||||
}
|
||||
|
||||
if ($integrationEntityIds) {
|
||||
if (is_array($integrationEntityIds)) {
|
||||
$q->andWhere('i.integration_entity_id in (:integrationEntityIds)')
|
||||
->setParameter('integrationEntityIds', $integrationEntityIds, ArrayParameterType::STRING);
|
||||
} else {
|
||||
$q->andWhere('i.integration_entity_id = :integrationEntityId')
|
||||
->setParameter('integrationEntityId', $integrationEntityIds);
|
||||
}
|
||||
}
|
||||
|
||||
if ($start) {
|
||||
$q->setFirstResult((int) $start);
|
||||
}
|
||||
|
||||
if ($limit) {
|
||||
$q->setMaxResults((int) $limit);
|
||||
}
|
||||
|
||||
return $q->executeQuery()->fetchAllAssociative();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getIntegrationEntity($integration, $integrationEntity, $internalEntity, $internalEntityId, $leadFields = null)
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->from(MAUTIC_TABLE_PREFIX.'integration_entity', 'i')
|
||||
->join('i', MAUTIC_TABLE_PREFIX.'leads', 'l', 'l.id = i.internal_entity_id');
|
||||
$q->select('i.integration_entity_id, i.integration_entity, i.id, i.internal_entity_id');
|
||||
if ($leadFields) {
|
||||
$q->addSelect($leadFields);
|
||||
}
|
||||
|
||||
$q->where(
|
||||
$q->expr()->and(
|
||||
$q->expr()->eq('i.integration', ':integration'),
|
||||
$q->expr()->eq('i.internal_entity', ':internalEntity'),
|
||||
$q->expr()->eq('i.integration_entity', ':integrationEntity'),
|
||||
$q->expr()->eq('i.internal_entity_id', (int) $internalEntityId)
|
||||
)
|
||||
)
|
||||
->setParameter('integration', $integration)
|
||||
->setParameter('internalEntity', $internalEntity)
|
||||
->setParameter('integrationEntity', $integrationEntity)
|
||||
->setMaxResults(1);
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
return ($results) ? $results[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IntegrationEntity[]
|
||||
*/
|
||||
public function getIntegrationEntities($integration, $integrationEntity, $internalEntity, $internalEntityIds)
|
||||
{
|
||||
$q = $this->createQueryBuilder('i', 'i.internalEntityId');
|
||||
|
||||
$q->where(
|
||||
$q->expr()->andX(
|
||||
$q->expr()->eq('i.integration', ':integration'),
|
||||
$q->expr()->eq('i.internalEntity', ':internalEntity'),
|
||||
$q->expr()->eq('i.integrationEntity', ':integrationEntity'),
|
||||
$q->expr()->in('i.internalEntityId', ':internalEntityIds')
|
||||
)
|
||||
)
|
||||
->setParameter('integration', $integration)
|
||||
->setParameter('internalEntity', $internalEntity)
|
||||
->setParameter('integrationEntity', $integrationEntity)
|
||||
->setParameter('internalEntityIds', $internalEntityIds);
|
||||
|
||||
return $q->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @param array|string $integrationEntity
|
||||
* @param array $excludeIntegrationIds
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function findLeadsToUpdate(
|
||||
$integration,
|
||||
$internalEntity,
|
||||
$leadFields,
|
||||
$limit = 25,
|
||||
$fromDate = null,
|
||||
$toDate = null,
|
||||
$integrationEntity = ['Contact', 'Lead'],
|
||||
$excludeIntegrationIds = [],
|
||||
): array {
|
||||
if ('company' == $internalEntity) {
|
||||
$joinTable = 'companies';
|
||||
} else {
|
||||
$joinTable = 'leads';
|
||||
}
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->from(MAUTIC_TABLE_PREFIX.'integration_entity', 'i')
|
||||
->join('i', MAUTIC_TABLE_PREFIX.$joinTable, 'l', 'l.id = i.internal_entity_id');
|
||||
|
||||
if (false === $limit) {
|
||||
$q->select('count(i.integration_entity_id) as total');
|
||||
|
||||
if ($integrationEntity) {
|
||||
$q->addSelect('i.integration_entity');
|
||||
}
|
||||
} else {
|
||||
$q->select('i.integration_entity_id, i.integration_entity, i.id, i.internal_entity_id,'.$leadFields);
|
||||
}
|
||||
|
||||
$q->where('i.integration = :integration');
|
||||
|
||||
if ($integrationEntity) {
|
||||
if (!is_array($integrationEntity)) {
|
||||
$integrationEntity = [$integrationEntity];
|
||||
}
|
||||
$sub = null;
|
||||
foreach ($integrationEntity as $key => $entity) {
|
||||
if (null === $sub) {
|
||||
$sub = CompositeExpression::or($q->expr()->eq('i.integration_entity', ':entity'.$key));
|
||||
$q->setParameter('entity'.$key, $entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
$sub->with($q->expr()->eq('i.integration_entity', ':entity'.$key));
|
||||
$q->setParameter('entity'.$key, $entity);
|
||||
}
|
||||
$q->andWhere($sub);
|
||||
}
|
||||
|
||||
$q->andWhere('i.internal_entity = :internalEntity')
|
||||
->setParameter('integration', $integration)
|
||||
->setParameter('internalEntity', $internalEntity);
|
||||
|
||||
if (!empty($excludeIntegrationIds)) {
|
||||
$q->andWhere(
|
||||
$q->expr()->notIn(
|
||||
'i.integration_entity_id',
|
||||
array_map(
|
||||
fn ($x): string => "'".$x."'",
|
||||
$excludeIntegrationIds
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$q->andWhere(
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNotNull('i.integration_entity_id'),
|
||||
$q->expr()->or(
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNotNull('i.last_sync_date'),
|
||||
$q->expr()->gt('l.date_modified', 'i.last_sync_date')
|
||||
),
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNull('i.last_sync_date'),
|
||||
$q->expr()->isNotNull('l.date_modified'),
|
||||
$q->expr()->gt('l.date_modified', 'l.date_added')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if ('lead' == $internalEntity) {
|
||||
$q->andWhere(
|
||||
$q->expr()->and($q->expr()->isNotNull('l.email')));
|
||||
} else {
|
||||
$q->andWhere(
|
||||
$q->expr()->and($q->expr()->isNotNull('l.companyname')));
|
||||
}
|
||||
|
||||
if ($fromDate) {
|
||||
if ($toDate) {
|
||||
$q->andWhere(
|
||||
$q->expr()->comparison('l.date_modified', 'BETWEEN', ':dateFrom and :dateTo')
|
||||
)
|
||||
->setParameter('dateFrom', $fromDate)
|
||||
->setParameter('dateTo', $toDate);
|
||||
} else {
|
||||
$q->andWhere(
|
||||
$q->expr()->gte('l.date_modified', ':dateFrom')
|
||||
)
|
||||
->setParameter('dateFrom', $fromDate);
|
||||
}
|
||||
} elseif ($toDate) {
|
||||
$q->andWhere(
|
||||
$q->expr()->lte('l.date_modified', ':dateTo')
|
||||
)
|
||||
->setParameter('dateTo', $toDate);
|
||||
}
|
||||
|
||||
// Group by email to prevent duplicates from affecting this
|
||||
|
||||
if (false === $limit and $integrationEntity) {
|
||||
$q->groupBy('i.integration_entity')->having('total');
|
||||
}
|
||||
if ($limit) {
|
||||
$q->setMaxResults($limit);
|
||||
}
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
$leads = [];
|
||||
|
||||
if ($integrationEntity) {
|
||||
foreach ($integrationEntity as $entity) {
|
||||
$leads[$entity] = (false === $limit) ? 0 : [];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($results as $result) {
|
||||
if ($integrationEntity) {
|
||||
if (false === $limit) {
|
||||
$leads[$result['integration_entity']] = (int) $result['total'];
|
||||
} else {
|
||||
$leads[$result['integration_entity']][$result['internal_entity_id']] = $result;
|
||||
}
|
||||
} else {
|
||||
$leads[$result['internal_entity_id']] = $result['internal_entity_id'];
|
||||
}
|
||||
}
|
||||
|
||||
return $leads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array|int
|
||||
*/
|
||||
public function findLeadsToCreate($integration, $leadFields, $limit = 25, $fromDate = null, $toDate = null, $internalEntity = 'lead')
|
||||
{
|
||||
if ('company' == $internalEntity) {
|
||||
$joinTable = 'companies';
|
||||
} else {
|
||||
$joinTable = 'leads';
|
||||
}
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->from(MAUTIC_TABLE_PREFIX.$joinTable, 'l');
|
||||
|
||||
if (false === $limit) {
|
||||
$q->select('count(*) as total');
|
||||
} else {
|
||||
$q->select('l.id as internal_entity_id,'.$leadFields);
|
||||
}
|
||||
if ('company' == $internalEntity) {
|
||||
$q->where('not exists (select null from '.MAUTIC_TABLE_PREFIX
|
||||
.'integration_entity i where i.integration = :integration and i.internal_entity LIKE "'.$internalEntity.'%" and i.internal_entity_id = l.id)')
|
||||
->setParameter('integration', $integration);
|
||||
} else {
|
||||
$q->where('l.date_identified is not null')
|
||||
->andWhere(
|
||||
'not exists (select null from '.MAUTIC_TABLE_PREFIX
|
||||
.'integration_entity i where i.integration = :integration and i.internal_entity LIKE "'.$internalEntity.'%" and i.internal_entity_id = l.id)'
|
||||
)
|
||||
->setParameter('integration', $integration);
|
||||
}
|
||||
|
||||
if ('company' == $internalEntity) {
|
||||
$q->andWhere('l.companyname is not null');
|
||||
} else {
|
||||
$q->andWhere('l.email is not null');
|
||||
}
|
||||
if ($limit) {
|
||||
$q->setMaxResults($limit);
|
||||
}
|
||||
|
||||
if ($fromDate) {
|
||||
if ($toDate) {
|
||||
$q->andWhere(
|
||||
$q->expr()->or(
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNotNull('l.date_modified'),
|
||||
$q->expr()->comparison('l.date_modified', 'BETWEEN', ':dateFrom and :dateTo')
|
||||
),
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNull('l.date_modified'),
|
||||
$q->expr()->comparison('l.date_added', 'BETWEEN', ':dateFrom and :dateTo')
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter('dateFrom', $fromDate)
|
||||
->setParameter('dateTo', $toDate);
|
||||
} else {
|
||||
$q->andWhere(
|
||||
$q->expr()->or(
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNotNull('l.date_modified'),
|
||||
$q->expr()->gte('l.date_modified', ':dateFrom')
|
||||
),
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNull('l.date_modified'),
|
||||
$q->expr()->gte('l.date_added', ':dateFrom')
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter('dateFrom', $fromDate);
|
||||
}
|
||||
} elseif ($toDate) {
|
||||
$q->andWhere(
|
||||
$q->expr()->or(
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNotNull('l.date_modified'),
|
||||
$q->expr()->lte('l.date_modified', ':dateTo')
|
||||
),
|
||||
$q->expr()->and(
|
||||
$q->expr()->isNull('l.date_modified'),
|
||||
$q->expr()->lte('l.date_added', ':dateTo')
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter('dateTo', $toDate);
|
||||
}
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
if (false === $limit) {
|
||||
return (int) $results[0]['total'];
|
||||
}
|
||||
|
||||
$leads = [];
|
||||
foreach ($results as $result) {
|
||||
$leads[$result['internal_entity_id']] = $result;
|
||||
}
|
||||
|
||||
return $leads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getIntegrationEntityCount($leadId, $integration = null, $integrationEntity = null, $internalEntity = null)
|
||||
{
|
||||
return $this->getIntegrationEntityByLead($leadId, $integration, $integrationEntity, $internalEntity, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|bool $limit
|
||||
*
|
||||
* @return array|int
|
||||
*/
|
||||
public function getIntegrationEntityByLead($leadId, $integration = null, $integrationEntity = null, $internalEntity = null, $limit = 100)
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->from(MAUTIC_TABLE_PREFIX.'integration_entity', 'i');
|
||||
|
||||
if (false === $limit) {
|
||||
$q->select('count(*) as total');
|
||||
} else {
|
||||
$q->select('i.integration, i.integration_entity, i.integration_entity_id, i.date_added, i.last_sync_date, i.internal');
|
||||
}
|
||||
|
||||
$q->where('i.internal not like \'%error%\' and i.integration_entity_id is not null');
|
||||
$q->orderBy('i.last_sync_date', 'DESC');
|
||||
|
||||
if (empty($integration)) {
|
||||
// get list of published integrations
|
||||
$pq = $this->_em->getConnection()->createQueryBuilder()
|
||||
->select('p.name')
|
||||
->from(MAUTIC_TABLE_PREFIX.'plugin_integration_settings', 'p')
|
||||
->where('p.is_published = 1');
|
||||
$rows = $pq->executeQuery()->fetchAllAssociative();
|
||||
$plugins = array_map(static fn ($i): string => "'{$i['name']}'", $rows);
|
||||
if (count($plugins) > 0) {
|
||||
$q->andWhere($q->expr()->in('i.integration', $plugins));
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
$q->andWhere($q->expr()->eq('i.integration', ':integration'));
|
||||
$q->setParameter('integration', $integration);
|
||||
}
|
||||
|
||||
$q->andWhere(
|
||||
$q->expr()->and(
|
||||
"i.internal_entity='lead'",
|
||||
$q->expr()->eq('i.internal_entity_id', ':internalEntityId')
|
||||
)
|
||||
);
|
||||
|
||||
$q->setParameter('internalEntityId', $leadId);
|
||||
|
||||
if (!empty($internalEntity)) {
|
||||
$q->andWhere($q->expr()->eq('i.internalEntity', ':internalEntity'));
|
||||
$q->setParameter('internalEntity', $internalEntity);
|
||||
}
|
||||
|
||||
if (!empty($integrationEntity)) {
|
||||
$q->andWhere($q->expr()->eq('i.integrationEntity', ':integrationEntity'));
|
||||
$q->setParameter('integrationEntity', $integrationEntity);
|
||||
}
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
if (false === $limit && count($results) > 0) {
|
||||
return (int) $results[0]['total'];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function markAsDeleted(array $integrationIds, $integration, $internalEntityType): void
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->update(MAUTIC_TABLE_PREFIX.'integration_entity')
|
||||
->set('internal_entity', ':entity')
|
||||
->where(
|
||||
$q->expr()->and(
|
||||
$q->expr()->eq('integration', ':integration'),
|
||||
$q->expr()->in('integration_entity_id', array_map([$q->expr(), 'literal'], $integrationIds))
|
||||
)
|
||||
)
|
||||
->setParameter('integration', $integration)
|
||||
->setParameter('entity', $internalEntityType.'-deleted')
|
||||
->executeStatement();
|
||||
}
|
||||
|
||||
public function findLeadsToDelete($internalEntity, $leadId): void
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->delete(MAUTIC_TABLE_PREFIX.'integration_entity')
|
||||
->from(MAUTIC_TABLE_PREFIX.'integration_entity');
|
||||
|
||||
$q->where('internal_entity_id = :leadId')
|
||||
->andWhere($q->expr()->like('internal_entity', ':internalEntity'))
|
||||
->setParameter('leadId', $leadId)
|
||||
->setParameter('internalEntity', $internalEntity)
|
||||
->executeStatement();
|
||||
}
|
||||
|
||||
public function updateErrorLeads($internalEntity, $leadId): void
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder()
|
||||
->update(MAUTIC_TABLE_PREFIX.'integration_entity')
|
||||
->set('internal_entity', ':lead')->setParameter('lead', 'lead');
|
||||
|
||||
$q->where('internal_entity_id = :leadId')
|
||||
->andWhere($q->expr()->isNotNull('integration_entity_id'))
|
||||
->andWhere($q->expr()->eq('internal_entity', ':internalEntity'))
|
||||
->setParameter('leadId', $leadId)
|
||||
->setParameter('internalEntity', $internalEntity)
|
||||
->executeStatement();
|
||||
|
||||
$z = $this->_em->getConnection()->createQueryBuilder()
|
||||
->delete(MAUTIC_TABLE_PREFIX.'integration_entity')
|
||||
->from(MAUTIC_TABLE_PREFIX.'integration_entity');
|
||||
|
||||
$z->where('internal_entity_id = :leadId')
|
||||
->andWhere($q->expr()->isNull('integration_entity_id'))
|
||||
->andWhere($q->expr()->like('internal_entity', ':internalEntity'))
|
||||
->setParameter('leadId', $leadId)
|
||||
->setParameter('internalEntity', $internalEntity)
|
||||
->executeStatement();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\PluginBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Query;
|
||||
use Mautic\CoreBundle\Cache\ResultCacheHelper;
|
||||
use Mautic\CoreBundle\Cache\ResultCacheOptions;
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<Integration>
|
||||
*/
|
||||
class IntegrationRepository extends CommonRepository
|
||||
{
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getIntegrations(): array
|
||||
{
|
||||
$query = $this->createQueryBuilder('i')
|
||||
->join('i.plugin', 'p')
|
||||
->getQuery();
|
||||
$this->enableCache($query);
|
||||
|
||||
$services = $query->getResult();
|
||||
|
||||
$results = [];
|
||||
foreach ($services as $s) {
|
||||
$results[$s->getName()] = $s;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get core (no plugin) integrations.
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getCoreIntegrations(): array
|
||||
{
|
||||
$query = $this->createQueryBuilder('i')
|
||||
->getQuery();
|
||||
$this->enableCache($query);
|
||||
|
||||
$services = $query->getResult();
|
||||
|
||||
$results = [];
|
||||
foreach ($services as $s) {
|
||||
$results[$s->getName()] = $s;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function findOneByName(string $name): ?Integration
|
||||
{
|
||||
$query = $this->createQueryBuilder('i')
|
||||
->where('i.name = :name')
|
||||
->setParameter('name', $name)
|
||||
->setMaxResults(1)
|
||||
->getQuery();
|
||||
$this->enableCache($query);
|
||||
|
||||
return $query->getOneOrNullResult();
|
||||
}
|
||||
|
||||
private function enableCache(Query $query): void
|
||||
{
|
||||
ResultCacheHelper::enableOrmQueryCache($query, new ResultCacheOptions(Integration::CACHE_NAMESPACE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\PluginBundle\Entity;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\CoreBundle\Entity\CacheInvalidateInterface;
|
||||
use Mautic\CoreBundle\Entity\CommonEntity;
|
||||
|
||||
class Plugin extends CommonEntity implements CacheInvalidateInterface
|
||||
{
|
||||
public const DESCRIPTION_DELIMITER_REGEX = "/\R---\R/";
|
||||
public const CACHE_NAMESPACE = 'Plugin';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $primaryDescription;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $secondaryDescription;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isMissing = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $bundle;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $author;
|
||||
|
||||
/**
|
||||
* @var ArrayCollection<int, Integration>
|
||||
*/
|
||||
private $integrations;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->integrations = new ArrayCollection();
|
||||
}
|
||||
|
||||
public static function loadMetadata(ORM\ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable('plugins')
|
||||
->setCustomRepositoryClass(PluginRepository::class)
|
||||
->addUniqueConstraint(['bundle'], 'unique_bundle');
|
||||
|
||||
$builder->addIdColumns();
|
||||
|
||||
$builder->createField('isMissing', 'boolean')
|
||||
->columnName('is_missing')
|
||||
->build();
|
||||
|
||||
$builder->createField('bundle', 'string')
|
||||
->length(50)
|
||||
->build();
|
||||
|
||||
$builder->createField('version', 'string')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('author', 'string')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createOneToMany('integrations', 'Integration')
|
||||
->setIndexBy('id')
|
||||
->mappedBy('plugin')
|
||||
->fetchExtraLazy()
|
||||
->build();
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
$this->id = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Plugin
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bundle
|
||||
*/
|
||||
public function setBundle($bundle): void
|
||||
{
|
||||
$this->bundle = $bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBundle()
|
||||
{
|
||||
return $this->bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIntegrations()
|
||||
{
|
||||
return $this->integrations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $description
|
||||
*/
|
||||
public function setDescription($description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
$this->splitDescriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPrimaryDescription()
|
||||
{
|
||||
return $this->primaryDescription ?: $this->description;
|
||||
}
|
||||
|
||||
public function hasSecondaryDescription(): bool
|
||||
{
|
||||
return $this->description && preg_match(self::DESCRIPTION_DELIMITER_REGEX, $this->description) >= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSecondaryDescription()
|
||||
{
|
||||
return $this->secondaryDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $version
|
||||
*/
|
||||
public function setVersion($version): void
|
||||
{
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIsMissing()
|
||||
{
|
||||
return $this->isMissing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $isMissing
|
||||
*/
|
||||
public function setIsMissing($isMissing): void
|
||||
{
|
||||
$this->isMissing = $isMissing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAuthor()
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $author
|
||||
*/
|
||||
public function setAuthor($author): void
|
||||
{
|
||||
$this->author = $author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits description into primary and secondary.
|
||||
*/
|
||||
public function splitDescriptions(): void
|
||||
{
|
||||
if ($this->hasSecondaryDescription()) {
|
||||
$parts = preg_split(self::DESCRIPTION_DELIMITER_REGEX, $this->description);
|
||||
$this->primaryDescription = trim($parts[0]);
|
||||
$this->secondaryDescription = trim($parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCacheNamespacesToDelete(): array
|
||||
{
|
||||
return [
|
||||
self::CACHE_NAMESPACE,
|
||||
Integration::CACHE_NAMESPACE,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\PluginBundle\Entity;
|
||||
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<Plugin>
|
||||
*/
|
||||
class PluginRepository extends CommonRepository
|
||||
{
|
||||
/**
|
||||
* Find an addon record by bundle name.
|
||||
*
|
||||
* @param string $bundle
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
*/
|
||||
public function findByBundle($bundle)
|
||||
{
|
||||
$q = $this->createQueryBuilder($this->getTableAlias());
|
||||
$q->where($q->expr()->eq('p.bundle', ':bundle'))
|
||||
->setParameter('bundle', $bundle);
|
||||
|
||||
return $q->getQuery()->getOneOrNullResult();
|
||||
}
|
||||
|
||||
public function getEntities(array $args = [])
|
||||
{
|
||||
$q = $this->_em->createQueryBuilder();
|
||||
$q->select($this->getTableAlias())
|
||||
->from(Plugin::class, $this->getTableAlias(), (!empty($args['index'])) ? $this->getTableAlias().'.'.$args['index'] : $this->getTableAlias().'.id');
|
||||
|
||||
$args['qb'] = $q;
|
||||
$args['ignore_paginator'] = true;
|
||||
|
||||
return parent::getEntities($args);
|
||||
}
|
||||
|
||||
protected function getDefaultOrder(): array
|
||||
{
|
||||
return [
|
||||
['p.name', 'ASC'],
|
||||
];
|
||||
}
|
||||
|
||||
public function getTableAlias(): string
|
||||
{
|
||||
return 'p';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user