Initial commit: CloudOps infrastructure platform
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\AssetBundle\Entity;
|
||||
|
||||
use Doctrine\Common\Collections\Order;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
use Mautic\ProjectBundle\Entity\ProjectRepositoryTrait;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<Asset>
|
||||
*/
|
||||
class AssetRepository extends CommonRepository
|
||||
{
|
||||
use ProjectRepositoryTrait;
|
||||
|
||||
/**
|
||||
* Get a list of entities.
|
||||
*
|
||||
* @return Paginator
|
||||
*/
|
||||
public function getEntities(array $args = [])
|
||||
{
|
||||
$q = $this
|
||||
->createQueryBuilder('a')
|
||||
->select('a')
|
||||
->leftJoin('a.category', 'c');
|
||||
|
||||
$args['qb'] = $q;
|
||||
|
||||
return parent::getEntities($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param int $limit
|
||||
* @param int $start
|
||||
* @param bool|false $viewOther
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAssetList($search = '', $limit = 10, $start = 0, $viewOther = false)
|
||||
{
|
||||
$q = $this->createQueryBuilder('a');
|
||||
$q->select('partial a.{id, title, path, alias, language}');
|
||||
|
||||
if (!empty($search)) {
|
||||
$q->andWhere($q->expr()->like('a.title', ':search'))
|
||||
->setParameter('search', "%{$search}%");
|
||||
}
|
||||
|
||||
if (!$viewOther) {
|
||||
$q->andWhere($q->expr()->eq('a.createdBy', ':id'))
|
||||
->setParameter('id', $this->currentUser->getId());
|
||||
}
|
||||
|
||||
$q->orderBy('a.title');
|
||||
|
||||
if (!empty($limit)) {
|
||||
$q->setFirstResult($start)
|
||||
->setMaxResults($limit);
|
||||
}
|
||||
|
||||
return $q->getQuery()->getArrayResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\QueryBuilder|\Doctrine\DBAL\Query\QueryBuilder $q
|
||||
*/
|
||||
protected function addCatchAllWhereClause($q, $filter): array
|
||||
{
|
||||
return $this->addStandardCatchAllWhereClause($q, $filter, [
|
||||
'a.title',
|
||||
'a.alias',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\QueryBuilder|\Doctrine\DBAL\Query\QueryBuilder $q
|
||||
*/
|
||||
protected function addSearchCommandWhereClause($q, $filter): array
|
||||
{
|
||||
[$expr, $parameters] = $this->addStandardSearchCommandWhereClause($q, $filter);
|
||||
if ($expr) {
|
||||
return [$expr, $parameters];
|
||||
}
|
||||
|
||||
$command = $field = $filter->command;
|
||||
$unique = $this->generateRandomParameterName();
|
||||
$returnParameter = false; // returning a parameter that is not used will lead to a Doctrine error
|
||||
switch ($command) {
|
||||
case $this->translator->trans('mautic.asset.asset.searchcommand.isexpired'):
|
||||
case $this->translator->trans('mautic.asset.asset.searchcommand.isexpired', [], null, 'en_US'):
|
||||
$expr = sprintf(
|
||||
"(a.isPublished = :%1\$s AND a.publishDown IS NOT NULL AND a.publishDown <> '' AND a.publishDown < CURRENT_TIMESTAMP())",
|
||||
$unique
|
||||
);
|
||||
$forceParameters = [$unique => true];
|
||||
break;
|
||||
case $this->translator->trans('mautic.asset.asset.searchcommand.ispending'):
|
||||
case $this->translator->trans('mautic.asset.asset.searchcommand.ispending', [], null, 'en_US'):
|
||||
$expr = sprintf(
|
||||
"(a.isPublished = :%1\$s AND a.publishUp IS NOT NULL AND a.publishUp <> '' AND a.publishUp > CURRENT_TIMESTAMP())",
|
||||
$unique
|
||||
);
|
||||
$forceParameters = [$unique => true];
|
||||
break;
|
||||
case $this->translator->trans('mautic.asset.asset.searchcommand.lang'):
|
||||
$langUnique = $this->generateRandomParameterName();
|
||||
$langValue = $filter->string.'_%';
|
||||
$forceParameters = [
|
||||
$langUnique => $langValue,
|
||||
$unique => $filter->string,
|
||||
];
|
||||
$expr = '('.$q->expr()->eq('a.language', ":$unique").' OR '.$q->expr()->like('a.language', ":$langUnique").')';
|
||||
$returnParameter = true;
|
||||
break;
|
||||
case $this->translator->trans('mautic.project.searchcommand.name'):
|
||||
case $this->translator->trans('mautic.project.searchcommand.name', [], null, 'en_US'):
|
||||
return $this->handleProjectFilter(
|
||||
$this->_em->getConnection()->createQueryBuilder(),
|
||||
'asset_id',
|
||||
'asset_projects_xref',
|
||||
$this->getTableAlias(),
|
||||
$filter->string,
|
||||
$filter->not
|
||||
);
|
||||
}
|
||||
|
||||
if ($expr && $filter->not) {
|
||||
$expr = $q->expr()->not($expr);
|
||||
}
|
||||
|
||||
if (!empty($forceParameters)) {
|
||||
$parameters = $forceParameters;
|
||||
} elseif (!$returnParameter) {
|
||||
$parameters = [];
|
||||
} else {
|
||||
$string = ($filter->strict) ? $filter->string : "%{$filter->string}%";
|
||||
$parameters = ["$unique" => $string];
|
||||
}
|
||||
|
||||
return [$expr, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getSearchCommands(): array
|
||||
{
|
||||
$commands = [
|
||||
'mautic.core.searchcommand.ispublished',
|
||||
'mautic.core.searchcommand.isunpublished',
|
||||
'mautic.core.searchcommand.isuncategorized',
|
||||
'mautic.core.searchcommand.ismine',
|
||||
'mautic.asset.asset.searchcommand.isexpired',
|
||||
'mautic.asset.asset.searchcommand.ispending',
|
||||
'mautic.core.searchcommand.category',
|
||||
'mautic.asset.asset.searchcommand.lang',
|
||||
'mautic.project.searchcommand.name',
|
||||
];
|
||||
|
||||
return array_merge($commands, parent::getSearchCommands());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<array<string>>
|
||||
*/
|
||||
protected function getDefaultOrder(): array
|
||||
{
|
||||
return [
|
||||
['a.title', 'ASC'],
|
||||
];
|
||||
}
|
||||
|
||||
public function getTableAlias(): string
|
||||
{
|
||||
return 'a';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sum size of assets.
|
||||
*/
|
||||
public function getAssetSize(array $assets): int
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->select('sum(a.size) as total_size')
|
||||
->from(MAUTIC_TABLE_PREFIX.'assets', 'a')
|
||||
->where('a.id IN (:assetIds)')
|
||||
->setParameter('assetIds', $assets, \Doctrine\DBAL\ArrayParameterType::INTEGER);
|
||||
|
||||
$result = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
return (int) $result[0]['total_size'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $increaseBy
|
||||
* @param bool|false $unique
|
||||
*/
|
||||
public function upDownloadCount($id, $increaseBy = 1, $unique = false): void
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
|
||||
$q->update(MAUTIC_TABLE_PREFIX.'assets')
|
||||
->set('download_count', 'download_count + '.(int) $increaseBy)
|
||||
->where('id = '.(int) $id);
|
||||
|
||||
if ($unique) {
|
||||
$q->set('unique_download_count', 'unique_download_count + '.(int) $increaseBy);
|
||||
}
|
||||
|
||||
$q->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $categoryId
|
||||
*
|
||||
* @return Asset
|
||||
*
|
||||
* @throws NoResultException
|
||||
* @throws NonUniqueResultException
|
||||
*/
|
||||
public function getLatestAssetForCategory($categoryId)
|
||||
{
|
||||
$q = $this->createQueryBuilder($this->getTableAlias());
|
||||
$q->where($this->getTableAlias().'.category = :categoryId');
|
||||
$q->andWhere($this->getTableAlias().'.isPublished = TRUE');
|
||||
$q->setParameter('categoryId', $categoryId);
|
||||
$q->orderBy($this->getTableAlias().'.dateAdded', Order::Descending->value);
|
||||
$q->setMaxResults(1);
|
||||
|
||||
return $q->getQuery()->getSingleResult();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\AssetBundle\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\CoreBundle\Entity\IpAddress;
|
||||
use Mautic\EmailBundle\Entity\Email;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(security: "is_granted('asset:assets:viewown')"),
|
||||
new Get(security: "is_granted('asset:assets:viewown')"),
|
||||
],
|
||||
normalizationContext: [
|
||||
'groups' => ['download:read'],
|
||||
'swagger_definition_name' => 'Read',
|
||||
'api_included' => ['asset', 'ipaddress', 'email'],
|
||||
],
|
||||
denormalizationContext: [
|
||||
'groups' => ['download:write'],
|
||||
'swagger_definition_name' => 'Write',
|
||||
]
|
||||
)]
|
||||
class Download
|
||||
{
|
||||
public const TABLE_NAME = 'asset_downloads';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
#[Groups(['download:read'])]
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $dateDownload;
|
||||
|
||||
/**
|
||||
* @var Asset|null
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $asset;
|
||||
|
||||
/**
|
||||
* @var IpAddress|null
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $ipAddress;
|
||||
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private ?Lead $lead;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $code;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $referer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $trackingId;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $source;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $sourceId;
|
||||
|
||||
/**
|
||||
* @var Email|null
|
||||
*/
|
||||
#[Groups(['download:read', 'download:write'])]
|
||||
private $email;
|
||||
|
||||
private ?string $utmCampaign = null;
|
||||
|
||||
private ?string $utmContent = null;
|
||||
|
||||
private ?string $utmMedium = null;
|
||||
|
||||
private ?string $utmSource = null;
|
||||
|
||||
private ?string $utmTerm = null;
|
||||
|
||||
public static function loadMetadata(ORM\ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable(self::TABLE_NAME)
|
||||
->setCustomRepositoryClass(DownloadRepository::class)
|
||||
->addIndex(['tracking_id'], 'download_tracking_search')
|
||||
->addIndex(['source', 'source_id'], 'download_source_search')
|
||||
->addIndex(['date_download'], 'asset_date_download');
|
||||
|
||||
$builder->addBigIntIdField();
|
||||
|
||||
$builder->createField('dateDownload', 'datetime')
|
||||
->columnName('date_download')
|
||||
->build();
|
||||
|
||||
$builder->createManyToOne('asset', 'Asset')
|
||||
->addJoinColumn('asset_id', 'id', true, false, 'CASCADE')
|
||||
->build();
|
||||
|
||||
$builder->addIpAddress(true);
|
||||
|
||||
$builder->addLead(true, 'SET NULL');
|
||||
|
||||
$builder->addField('code', 'integer');
|
||||
|
||||
$builder->createField('referer', 'text')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('trackingId', 'string')
|
||||
->columnName('tracking_id')
|
||||
->build();
|
||||
|
||||
$builder->createField('source', 'string')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('sourceId', 'integer')
|
||||
->columnName('source_id')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createManyToOne('email', Email::class)
|
||||
->addJoinColumn('email_id', 'id', true, false, 'SET NULL')
|
||||
->build();
|
||||
|
||||
$builder->createField('utmCampaign', Types::STRING)
|
||||
->columnName('utm_campaign')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('utmContent', Types::STRING)
|
||||
->columnName('utm_content')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('utmMedium', Types::STRING)
|
||||
->columnName('utm_medium')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('utmSource', Types::STRING)
|
||||
->columnName('utm_source')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('utmTerm', Types::STRING)
|
||||
->columnName('utm_term')
|
||||
->nullable()
|
||||
->build();
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return (int) $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $dateDownload
|
||||
*
|
||||
* @return Download
|
||||
*/
|
||||
public function setDateDownload($dateDownload)
|
||||
{
|
||||
$this->dateDownload = $dateDownload;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getDateDownload()
|
||||
{
|
||||
return $this->dateDownload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
*
|
||||
* @return Download
|
||||
*/
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $referer
|
||||
*
|
||||
* @return Download
|
||||
*/
|
||||
public function setReferer($referer)
|
||||
{
|
||||
$this->referer = $referer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getReferer()
|
||||
{
|
||||
return $this->referer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Download
|
||||
*/
|
||||
public function setAsset(?Asset $asset = null)
|
||||
{
|
||||
$this->asset = $asset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Asset
|
||||
*/
|
||||
public function getAsset()
|
||||
{
|
||||
return $this->asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Download
|
||||
*/
|
||||
public function setIpAddress(IpAddress $ipAddress)
|
||||
{
|
||||
$this->ipAddress = $ipAddress;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IpAddress
|
||||
*/
|
||||
public function getIpAddress()
|
||||
{
|
||||
return $this->ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $trackingId
|
||||
*
|
||||
* @return Download
|
||||
*/
|
||||
public function setTrackingId($trackingId)
|
||||
{
|
||||
$this->trackingId = $trackingId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTrackingId()
|
||||
{
|
||||
return $this->trackingId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLead()
|
||||
{
|
||||
return $this->lead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $lead
|
||||
*/
|
||||
public function setLead($lead): void
|
||||
{
|
||||
$this->lead = $lead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSource()
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $source
|
||||
*/
|
||||
public function setSource($source): void
|
||||
{
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSourceId()
|
||||
{
|
||||
return $this->sourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $sourceId
|
||||
*/
|
||||
public function setSourceId($sourceId): void
|
||||
{
|
||||
$this->sourceId = (int) $sourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $email
|
||||
*/
|
||||
public function setEmail(Email $email): void
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function getUtmCampaign(): ?string
|
||||
{
|
||||
return $this->utmCampaign;
|
||||
}
|
||||
|
||||
public function setUtmCampaign(?string $utmCampaign): static
|
||||
{
|
||||
$this->utmCampaign = $utmCampaign;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUtmContent(): ?string
|
||||
{
|
||||
return $this->utmContent;
|
||||
}
|
||||
|
||||
public function setUtmContent(?string $utmContent): static
|
||||
{
|
||||
$this->utmContent = $utmContent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUtmMedium(): ?string
|
||||
{
|
||||
return $this->utmMedium;
|
||||
}
|
||||
|
||||
public function setUtmMedium(?string $utmMedium): static
|
||||
{
|
||||
$this->utmMedium = $utmMedium;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUtmSource(): ?string
|
||||
{
|
||||
return $this->utmSource;
|
||||
}
|
||||
|
||||
public function setUtmSource(?string $utmSource): static
|
||||
{
|
||||
$this->utmSource = $utmSource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUtmTerm(): ?string
|
||||
{
|
||||
return $this->utmTerm;
|
||||
}
|
||||
|
||||
public function setUtmTerm(?string $utmTerm): static
|
||||
{
|
||||
$this->utmTerm = $utmTerm;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\AssetBundle\Entity;
|
||||
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
use Mautic\CoreBundle\Helper\Chart\PieChart;
|
||||
use Mautic\CoreBundle\Helper\DateTimeHelper;
|
||||
use Mautic\LeadBundle\Entity\TimelineTrait;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<Download>
|
||||
*/
|
||||
class DownloadRepository extends CommonRepository
|
||||
{
|
||||
use TimelineTrait;
|
||||
|
||||
/**
|
||||
* Determine if the download is a unique download.
|
||||
*/
|
||||
public function isUniqueDownload($assetId, $trackingId): bool
|
||||
{
|
||||
$q = $this->getEntityManager()->getConnection()->createQueryBuilder();
|
||||
$q2 = $this->getEntityManager()->getConnection()->createQueryBuilder();
|
||||
|
||||
$q2->select('null')
|
||||
->from(MAUTIC_TABLE_PREFIX.'asset_downloads', 'd');
|
||||
|
||||
$q2->where(
|
||||
$q2->expr()->and(
|
||||
$q2->expr()->eq('d.tracking_id', ':id'),
|
||||
$q2->expr()->eq('d.asset_id', (int) $assetId)
|
||||
)
|
||||
);
|
||||
|
||||
$q->select('u.is_unique')
|
||||
->from(sprintf('(SELECT (NOT EXISTS (%s)) is_unique)', $q2->getSQL()), 'u'
|
||||
)
|
||||
->setParameter('id', $trackingId);
|
||||
|
||||
return (bool) $q->executeQuery()->fetchOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lead's page downloads.
|
||||
*
|
||||
* @param int|null $leadId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLeadDownloads($leadId = null, array $options = [])
|
||||
{
|
||||
$query = $this->getEntityManager()->getConnection()->createQueryBuilder()
|
||||
->select('a.id as asset_id, d.date_download as dateDownload, a.title, d.id as download_id, d.lead_id')
|
||||
->from(MAUTIC_TABLE_PREFIX.'asset_downloads', 'd')
|
||||
->leftJoin('d', MAUTIC_TABLE_PREFIX.'assets', 'a', 'd.asset_id = a.id');
|
||||
|
||||
if ($leadId) {
|
||||
$query->where('d.lead_id = :leadId')
|
||||
->setParameter('leadId', $leadId);
|
||||
}
|
||||
|
||||
if (isset($options['search']) && $options['search']) {
|
||||
$query->andWhere('a.title LIKE :search')
|
||||
->setParameter('search', '%'.$options['search'].'%');
|
||||
}
|
||||
|
||||
return $this->getTimelineResults($query, $options, 'a.title', 'd.date_download', [], ['date_download'], null, 'd.id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of assets ordered by it's download count.
|
||||
*
|
||||
* @param QueryBuilder $query
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws \Doctrine\ORM\NoResultException
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
*/
|
||||
public function getMostDownloaded($query, $limit = 10, $offset = 0): array
|
||||
{
|
||||
$query->select('a.title, a.id, count(ad.id) as downloads')
|
||||
->groupBy('a.id, a.title')
|
||||
->orderBy('downloads', 'DESC')
|
||||
->setMaxResults($limit)
|
||||
->setFirstResult($offset);
|
||||
|
||||
return $query->executeQuery()->fetchAllAssociative();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of asset referrals ordered by it's count.
|
||||
*
|
||||
* @param QueryBuilder $query
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws \Doctrine\ORM\NoResultException
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
*/
|
||||
public function getTopReferrers($query, $limit = 10, $offset = 0): array
|
||||
{
|
||||
$query->select('ad.referer, count(ad.referer) as downloads')
|
||||
->groupBy('ad.referer')
|
||||
->orderBy('downloads', 'DESC')
|
||||
->setMaxResults($limit)
|
||||
->setFirstResult($offset);
|
||||
|
||||
return $query->executeQuery()->fetchAllAssociative();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pie graph data for http statuses.
|
||||
*
|
||||
* @param QueryBuilder $query
|
||||
*
|
||||
* @throws \Doctrine\ORM\NoResultException
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
*/
|
||||
public function getHttpStatuses($query): array
|
||||
{
|
||||
$query->select('ad.code as status, count(ad.code) as count')
|
||||
->groupBy('ad.code')
|
||||
->orderBy('count', 'DESC');
|
||||
|
||||
$results = $query->executeQuery()->fetchAllAssociative();
|
||||
|
||||
$chart = new PieChart();
|
||||
|
||||
foreach ($results as $result) {
|
||||
$chart->setDataset($result['status'], $result['count']);
|
||||
}
|
||||
|
||||
return $chart->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed, array<string, mixed>>
|
||||
*/
|
||||
public function getDownloadCountsByPage($pageId, ?\DateTime $fromDate = null): array
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->select('count(distinct(a.tracking_id)) as count, a.source_id as id, p.title as name, p.hits as total')
|
||||
->from(MAUTIC_TABLE_PREFIX.'asset_downloads', 'a')
|
||||
->join('a', MAUTIC_TABLE_PREFIX.'pages', 'p', 'a.source_id = p.id');
|
||||
|
||||
if (is_array($pageId)) {
|
||||
$q->where($q->expr()->in('p.id', $pageId))
|
||||
->groupBy('p.id, a.source_id, p.title, p.hits');
|
||||
} else {
|
||||
$q->where($q->expr()->eq('p.id', ':page'))
|
||||
->setParameter('page', (int) $pageId);
|
||||
}
|
||||
|
||||
$q->andWhere('a.source = "page"')
|
||||
->andWhere('a.code = 200');
|
||||
|
||||
if (null != $fromDate) {
|
||||
$dh = new DateTimeHelper($fromDate);
|
||||
$q->andWhere($q->expr()->gte('a.date_download', ':date'))
|
||||
->setParameter('date', $dh->toUtcString());
|
||||
}
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
$downloads = [];
|
||||
foreach ($results as $r) {
|
||||
$downloads[$r['id']] = $r;
|
||||
}
|
||||
|
||||
return $downloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get download count by email by linking emails that have been associated with a page hit that has the
|
||||
* same tracking ID as an asset download tracking ID and thus assumed happened in the same session.
|
||||
*
|
||||
* @return array<mixed, array<string, mixed>>
|
||||
*/
|
||||
public function getDownloadCountsByEmail($emailId, ?\DateTime $fromDate = null): array
|
||||
{
|
||||
// link email to page hit tracking id to download tracking id
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->select('count(distinct(a.tracking_id)) as count, e.id, e.subject as name, e.variant_sent_count as total')
|
||||
->from(MAUTIC_TABLE_PREFIX.'asset_downloads', 'a')
|
||||
->join('a', MAUTIC_TABLE_PREFIX.'emails', 'e', 'a.email_id = e.id');
|
||||
|
||||
if (is_array($emailId)) {
|
||||
$q->where($q->expr()->in('e.id', $emailId))
|
||||
->groupBy('e.id, e.subject, e.variant_sent_count');
|
||||
} else {
|
||||
$q->where($q->expr()->eq('e.id', ':email'))
|
||||
->setParameter('email', (int) $emailId);
|
||||
}
|
||||
|
||||
$q->andWhere('a.code = 200');
|
||||
|
||||
if (null != $fromDate) {
|
||||
$dh = new DateTimeHelper($fromDate);
|
||||
$q->andWhere($q->expr()->gte('a.date_download', ':date'))
|
||||
->setParameter('date', $dh->toUtcString());
|
||||
}
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
$downloads = [];
|
||||
foreach ($results as $r) {
|
||||
$downloads[$r['id']] = $r;
|
||||
}
|
||||
|
||||
return $downloads;
|
||||
}
|
||||
|
||||
public function updateLeadByTrackingId($leadId, $newTrackingId, $oldTrackingId): void
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->update(MAUTIC_TABLE_PREFIX.'asset_downloads')
|
||||
->set('lead_id', (int) $leadId)
|
||||
->set('tracking_id', ':newTrackingId')
|
||||
->where(
|
||||
$q->expr()->eq('tracking_id', ':oldTrackingId')
|
||||
)
|
||||
->setParameters([
|
||||
'newTrackingId' => $newTrackingId,
|
||||
'oldTrackingId' => $oldTrackingId,
|
||||
])
|
||||
->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates lead ID (e.g. after a lead merge).
|
||||
*/
|
||||
public function updateLead($fromLeadId, $toLeadId): void
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->update(MAUTIC_TABLE_PREFIX.'asset_downloads')
|
||||
->set('lead_id', (int) $toLeadId)
|
||||
->where('lead_id = '.(int) $fromLeadId)
|
||||
->executeStatement();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user