Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<?php
namespace Mautic\ReportBundle\Event;
use Mautic\ReportBundle\Entity\Report;
use Symfony\Contracts\EventDispatcher\Event;
class AbstractReportEvent extends Event
{
protected ?string $context = null;
/**
* Report entity.
*
* @var Report
*/
protected $report;
/**
* @return Report
*/
public function getReport()
{
return $this->report;
}
public function getContext(): ?string
{
return $this->context;
}
/**
* @return bool
*/
public function checkContext($context)
{
if (empty($this->context)) {
return true;
}
if (is_array($context)) {
$res = array_filter($context, fn ($elem) => 0 === stripos($this->context, (string) $elem));
return count($res) > 0;
} elseif ($this->context == $context) {
return true;
} elseif (0 === stripos($this->context, (string) $context)) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace Mautic\ReportBundle\Event;
use Symfony\Contracts\EventDispatcher\Event;
final class ColumnCollectEvent extends Event
{
/**
* @var array<string, mixed>
*/
private array $columns;
/**
* @param array<string, mixed> $properties
*/
public function __construct(
private string $object,
private array $properties = [],
) {
$this->columns = [];
}
public function getObject(): string
{
return $this->object;
}
/**
* @return array<string, mixed>
*/
public function getProperties(): array
{
return $this->properties;
}
/**
* @param array<string, array<string, mixed>> $column
*/
public function addColumns(array $column): void
{
$this->columns = array_merge($this->columns, $column);
}
/**
* @return array<string, array<string, mixed>>
*/
public function getColumns(): array
{
return $this->columns;
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Mautic\ReportBundle\Event;
use Mautic\ReportBundle\Entity\Report;
class PermanentReportFileCreatedEvent extends AbstractReportEvent
{
public function __construct(Report $report)
{
$this->report = $report;
}
}

View File

@@ -0,0 +1,300 @@
<?php
namespace Mautic\ReportBundle\Event;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Mautic\ChannelBundle\Helper\ChannelListHelper;
use Mautic\ReportBundle\Builder\MauticReportBuilder;
use Mautic\ReportBundle\Helper\ReportHelper;
use Mautic\ReportBundle\Model\ReportModel;
use Symfony\Contracts\Translation\TranslatorInterface;
class ReportBuilderEvent extends AbstractReportEvent
{
/**
* Container with registered tables and columns.
*/
private array $tableArray = [];
/**
* @var string[]
*/
private array $supportedGraphs = [
'table',
'bar',
'pie',
'line',
];
/**
* @var mixed[]
*/
private array $graphArray = [];
/**
* @param mixed[]|Paginator|array $leadFields list of published array of lead fields
*/
public function __construct(
private TranslatorInterface $translator,
private ChannelListHelper $channelListHelper,
string $context,
private array|Paginator $leadFields,
private ReportHelper $reportHelper,
private ?string $reportSource = null,
) {
$this->context = $context;
}
/**
* Add a table with the specified columns to the lookup.
*
* The data should be an associative array with the following data:
* 'display_name' => The translation key to display in the select list
* 'columns' => An array containing the table's columns
*
* @param string $context Context for data
* @param array $data Data array for the table
*
* @return ReportBuilderEvent
*/
public function addTable($context, array $data, $group = null)
{
$data['group'] = (null == $group) ? $context : $group;
foreach ($data['columns'] as $column => &$d) {
$d['label'] = null !== $d['label'] ? $this->translator->trans($d['label']) : '';
if (!isset($d['alias'])) {
$d['alias'] = substr(
$column,
false !== ($pos = strpos($column, '.')) ? $pos + 1 : 0
);
}
}
uasort($data['columns'], fn ($a, $b) => strnatcmp((string) $a['label'], (string) $b['label']));
if (isset($data['filters'])) {
foreach ($data['filters'] as $column => &$d) {
$d['label'] = $this->translator->trans($d['label']);
if (!isset($d['alias'])) {
$d['alias'] = substr(
$column,
false !== ($pos = strpos($column, '.')) ? $pos + 1 : 0
);
}
}
uasort($data['filters'], fn ($a, $b) => strnatcmp((string) $a['label'], (string) $b['label']));
}
$this->tableArray[$context] = $data;
if ($this->context == $context) {
$this->stopPropagation();
}
return $this;
}
/**
* Fetch the tables in the lookup array.
*
* @return array
*/
public function getTables()
{
return $this->tableArray;
}
/**
* Fetch the source of the report.
*/
public function getReportSource(): ?string
{
return $this->reportSource;
}
/**
* Returns standard form fields such as id, name, publish_up, etc.
*
* @param string $prefix
*
* @return array<string,array<string,string>>
*/
public function getStandardColumns($prefix, $removeColumns = [], $idLink = null): array
{
return $this->reportHelper->getStandardColumns($prefix, $removeColumns, (string) $idLink);
}
/**
* Returns lead columns.
*/
public function getLeadColumns($prefix = 'l.'): array
{
$fields = [];
foreach ($this->leadFields as $fieldArray) {
$fields[$prefix.$fieldArray['alias']] = [
'label' => $this->translator->trans('mautic.report.field.lead.label', ['%field%' => $fieldArray['label']]),
'type' => $this->reportHelper->getReportBuilderFieldType($fieldArray['type']),
'alias' => $fieldArray['alias'],
];
}
$fields[$prefix.'id'] = [
'label' => 'mautic.report.field.lead.id',
'type' => 'int',
'link' => 'mautic_contact_action',
'alias' => 'contactId',
];
return $fields;
}
/**
* Get IP Address column.
*
* @param string $prefix
*/
public function getIpColumn($prefix = 'i.'): array
{
return [
$prefix.'ip_address' => [
'label' => 'mautic.core.ipaddress',
'type' => 'string',
],
];
}
/**
* Add category columns.
*
* @param string $prefix
*/
public function getCategoryColumns($prefix = 'c.'): array
{
return [
$prefix.'id' => [
'label' => 'mautic.report.field.category_id',
'type' => 'int',
'alias' => 'category_id',
],
$prefix.'title' => [
'label' => 'mautic.report.field.category_name',
'type' => 'string',
'alias' => 'category_title',
],
];
}
/**
* Add campaign columns joined by the campaign lead event log table.
*/
public function getCampaignByChannelColumns(): array
{
return [
'clel.campaign_id' => [
'label' => 'mautic.campaign.campaign.id',
'type' => 'string',
],
'cmp.name' => [
'label' => 'mautic.campaign.campaign',
'type' => 'string',
],
];
}
/**
* @return array<MauticReportBuilder::*, mixed[]>
*/
public function getChannelColumns(): array
{
$channelColumns = [
MauticReportBuilder::CHANNEL_COLUMN_CATEGORY_ID => [
'label' => 'mautic.report.campaign.channel.category_id',
'type' => 'int',
'alias' => 'channel_category_id',
'channelData' => [],
],
MauticReportBuilder::CHANNEL_COLUMN_CREATED_BY => [
'label' => 'mautic.report.campaign.channel.created_by',
'type' => 'int',
'alias' => 'channel_created_by',
'channelData' => [],
],
MauticReportBuilder::CHANNEL_COLUMN_CREATED_BY_USER => [
'label' => 'mautic.report.campaign.channel.created_by_user',
'type' => 'string',
'alias' => 'channel_created_by_user',
'channelData' => [],
],
MauticReportBuilder::CHANNEL_COLUMN_DATE_ADDED => [
'label' => 'mautic.report.campaign.channel.date_added',
'type' => 'datetime',
'alias' => 'channel_date_added',
'channelData' => [],
],
MauticReportBuilder::CHANNEL_COLUMN_DESCRIPTION => [
'label' => 'mautic.report.campaign.channel.description',
'type' => 'string',
'alias' => 'channel_description',
'channelData' => [],
],
MauticReportBuilder::CHANNEL_COLUMN_NAME => [
'label' => 'mautic.report.campaign.channel.name',
'type' => 'string',
'alias' => 'channel_name',
'channelData' => [],
],
];
foreach ($this->channelListHelper->getChannels() as $channel => $details) {
if (!array_key_exists(ReportModel::CHANNEL_FEATURE, $details)) {
continue;
}
$reportDetails = $details[ReportModel::CHANNEL_FEATURE];
$hasFields = array_key_exists('fields', $reportDetails) && is_array($reportDetails['fields']);
foreach ($channelColumns as $column => $definition) {
$channelColumnName = $hasFields && array_key_exists($column, $reportDetails['fields'])
? $reportDetails['fields'][$column]
: str_replace('channel.', $channel.'.', $column);
$channelColumns[$column]['channelData'][$channel] = [
'prefix' => $channel,
'column' => $channelColumnName,
];
}
}
return $channelColumns;
}
/**
* @param array $options
*
* @return $this
*/
public function addGraph($context, $type, $graphId, $options = [])
{
if (in_array($type, $this->supportedGraphs)) {
$this->graphArray[$context][$graphId] = [
'options' => $options,
'type' => $type,
];
}
return $this;
}
/**
* Get graphs.
*
* @return array
*/
public function getGraphs()
{
return $this->graphArray;
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Mautic\ReportBundle\Event;
use Mautic\ReportBundle\Entity\Report;
class ReportDataEvent extends AbstractReportEvent
{
private int $totalResults;
public function __construct(
Report $report,
private array $data,
$totalResults,
private array $options,
) {
$this->context = $report->getSource();
$this->report = $report;
$this->totalResults = (int) $totalResults;
}
/**
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* @param array $data
*/
public function setData($data): void
{
$this->data = $data;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
public function getTotalResults(): int
{
return $this->totalResults;
}
public function updateColumnType(string $alias, string $type): void
{
foreach ($this->options['columns'] as &$column) {
if ($column['alias'] === $alias) {
$column['type'] = $type;
break;
}
}
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Mautic\ReportBundle\Event;
use Mautic\CoreBundle\Event\CommonEvent;
use Mautic\ReportBundle\Entity\Report;
class ReportEvent extends CommonEvent
{
/**
* @param bool $isNew
*/
public function __construct(Report $report, $isNew = false)
{
$this->entity = $report;
$this->isNew = $isNew;
}
/**
* Returns the Report entity.
*
* @return Report
*/
public function getReport()
{
return $this->entity;
}
/**
* Sets the Report entity.
*/
public function setReport(Report $report): void
{
$this->entity = $report;
}
}

View File

@@ -0,0 +1,461 @@
<?php
namespace Mautic\ReportBundle\Event;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\QueryBuilder;
use Mautic\ChannelBundle\Helper\ChannelListHelper;
use Mautic\ReportBundle\Entity\Report;
use Mautic\ReportBundle\Model\ReportModel;
class ReportGeneratorEvent extends AbstractReportEvent
{
public const CATEGORY_PREFIX = 'c';
public const CONTACT_PREFIX = 'l';
public const COMPANY_PREFIX = 'comp';
public const COMPANY_LEAD_PREFIX = 'companies_lead';
public const IP_ADDRESS_PREFIX = 'i';
private array $selectColumns = [];
private ?string $contentTemplate = null;
private ?ExpressionBuilder $filterExpression = null;
private ?array $sortedFilters = null;
public function __construct(
Report $report,
private array $options,
private QueryBuilder $queryBuilder,
private ChannelListHelper $channelListHelper,
) {
$this->report = $report;
$this->context = $report->getSource();
}
public function getQueryBuilder(): QueryBuilder
{
return $this->queryBuilder;
}
public function setQueryBuilder(QueryBuilder $queryBuilder): self
{
$this->queryBuilder = $queryBuilder;
return $this;
}
public function getContentTemplate(): ?string
{
if ($this->contentTemplate) {
return $this->contentTemplate;
}
// Default content template
return '@MauticReport/Report/details.html.twig';
}
public function setContentTemplate(?string $contentTemplate): self
{
$this->contentTemplate = $contentTemplate;
return $this;
}
/**
* @return array
*/
public function getSelectColumns()
{
return $this->selectColumns;
}
/**
* Set custom select columns with aliases based on report settings.
*/
public function setSelectColumns(array $selectColumns): self
{
$this->selectColumns = $selectColumns;
return $this;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @return $this
*/
public function setOptions(array $options)
{
$this->options = array_merge($this->options, $options);
return $this;
}
public function getFilterExpression(): ?ExpressionBuilder
{
return $this->filterExpression;
}
public function setFilterExpression(ExpressionBuilder $filterExpression): self
{
$this->filterExpression = $filterExpression;
return $this;
}
/**
* Add category left join.
*
* @param string $prefix
* @param string $categoryPrefix
*/
public function addCategoryLeftJoin(QueryBuilder $queryBuilder, $prefix, $categoryPrefix = self::CATEGORY_PREFIX): self
{
if ($this->usesColumnWithPrefix($categoryPrefix)) {
$queryBuilder->leftJoin($prefix, MAUTIC_TABLE_PREFIX.'categories', $categoryPrefix, $categoryPrefix.'.id = '.$prefix.'.category_id');
}
return $this;
}
/**
* Add lead left join.
*
* @param string $prefix
* @param string $leadPrefix
*/
public function addLeadLeftJoin(QueryBuilder $queryBuilder, $prefix, $leadPrefix = self::CONTACT_PREFIX): self
{
if ($this->usesColumnWithPrefix($leadPrefix)
|| $this->usesColumnWithPrefix(self::IP_ADDRESS_PREFIX)
|| $this->usesColumnWithPrefix(self::COMPANY_PREFIX)
|| $this->usesColumn('cmp.name')
|| $this->usesColumn('clel.campaign_id')
|| $this->usesColumn('dnc_preferences')
) {
$queryBuilder->leftJoin($prefix, MAUTIC_TABLE_PREFIX.'leads', $leadPrefix, $leadPrefix.'.id = '.$prefix.'.lead_id');
}
return $this;
}
/**
* Add IP left join.
*
* @param string $prefix
* @param string $ipPrefix
*/
public function addIpAddressLeftJoin(QueryBuilder $queryBuilder, $prefix, $ipPrefix = self::IP_ADDRESS_PREFIX): self
{
if ($this->usesColumnWithPrefix($ipPrefix)) {
$queryBuilder->leftJoin($prefix, MAUTIC_TABLE_PREFIX.'ip_addresses', $ipPrefix, $ipPrefix.'.id = '.$prefix.'.ip_id');
}
return $this;
}
/**
* Add IP left join with lead join.
*
* @param string $ipXrefPrefix
* @param string $ipPrefix
* @param string $leadPrefix
*/
public function addLeadIpAddressLeftJoin(QueryBuilder $queryBuilder, $ipXrefPrefix = 'lip', $ipPrefix = self::IP_ADDRESS_PREFIX, $leadPrefix = self::CONTACT_PREFIX): self
{
if ($this->usesColumnWithPrefix($ipPrefix)) {
$this->addIpAddressLeftJoin($queryBuilder, $ipXrefPrefix, $ipPrefix);
$queryBuilder->leftJoin($leadPrefix, MAUTIC_TABLE_PREFIX.'lead_ips_xref', $ipXrefPrefix, $ipXrefPrefix.'.lead_id = '.$leadPrefix.'.id');
}
return $this;
}
/**
* Add IP left join.
*
* @param string $prefix
* @param string $channel
* @param string $leadPrefix
* @param string $onColumn
*/
public function addCampaignByChannelJoin(QueryBuilder $queryBuilder, $prefix, $channel, $leadPrefix = self::CONTACT_PREFIX, $onColumn = 'id'): self
{
if ($this->usesColumn('cmp.name') || $this->usesColumn('clel.campaign_id')) {
$condition = "clel.channel='{$channel}' AND {$prefix}.{$onColumn} = clel.channel_id AND clel.lead_id = {$leadPrefix}.id";
$queryBuilder->leftJoin($prefix, MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'clel', $condition);
$queryBuilder->leftJoin('clel', MAUTIC_TABLE_PREFIX.'campaigns', 'cmp', 'cmp.id = clel.campaign_id');
}
return $this;
}
/**
* Join channel columns.
*
* @param string $prefix
*/
public function addChannelLeftJoins(QueryBuilder $queryBuilder, $prefix): self
{
foreach ($this->channelListHelper->getChannels() as $channel => $details) {
if (!array_key_exists(ReportModel::CHANNEL_FEATURE, $details)) {
continue;
}
$reportDetails = $details[ReportModel::CHANNEL_FEATURE];
if (!array_key_exists('table', $reportDetails)) {
continue;
}
$channelParameter = 'channelParameter'.$channel;
$queryBuilder->leftJoin(
$prefix,
MAUTIC_TABLE_PREFIX.$reportDetails['table'],
$channel,
$prefix.'.channel_id = '.$channel.'.id AND '.$prefix.'.channel = :'.$channelParameter
);
$queryBuilder->setParameter($channelParameter, $channel);
}
return $this;
}
/**
* Add company left join.
*/
public function addCompanyLeftJoin(QueryBuilder $queryBuilder, string $companyPrefix = self::COMPANY_PREFIX, string $contactPrefix = self::CONTACT_PREFIX): void
{
if ($this->usesColumnWithPrefix($companyPrefix) || $this->usesColumnWithPrefix(self::COMPANY_LEAD_PREFIX)) {
if ($this->isJoined($queryBuilder, MAUTIC_TABLE_PREFIX.'companies_leads', 'l', self::COMPANY_LEAD_PREFIX)) {
return;
}
$queryBuilder->leftJoin('l', MAUTIC_TABLE_PREFIX.'companies_leads', self::COMPANY_LEAD_PREFIX, $contactPrefix.'.id ='.self::COMPANY_LEAD_PREFIX.'.lead_id');
$queryBuilder->leftJoin(self::COMPANY_LEAD_PREFIX, MAUTIC_TABLE_PREFIX.'companies', $companyPrefix, self::COMPANY_LEAD_PREFIX.'.company_id = '.$companyPrefix.'.id');
}
}
/**
* Apply date filters to the query.
*
* @param string $dateColumn
* @param string $tablePrefix
* @param bool $dateOnly
*
* @throws \Exception
*/
public function applyDateFilters(QueryBuilder $queryBuilder, $dateColumn, $tablePrefix = 't', $dateOnly = false): ReportGeneratorEvent
{
$this->setDateRangeQueryFilters(
$queryBuilder, $tablePrefix, $dateOnly, $dateColumn,
'%1$s IS NULL OR (DATE(%1$s) BETWEEN :dateFrom AND :dateTo)',
'%1$s IS NULL OR (%1$s BETWEEN :dateFrom AND :dateTo)'
);
return $this;
}
public function applyDateFiltersWithoutNullValues(QueryBuilder $queryBuilder, string $dateColumn, string $tablePrefix = 't', bool $dateOnly = false): ReportGeneratorEvent
{
$this->setDateRangeQueryFilters(
$queryBuilder, $tablePrefix, $dateOnly, $dateColumn,
'DATE(%1$s) BETWEEN :dateFrom AND :dateTo',
'%1$s BETWEEN :dateFrom AND :dateTo'
);
return $this;
}
public function hasColumnWithPrefix(string $prefix): bool
{
$columns = $this->getReport()->getSelectAndAggregatorAndOrderAndGroupByColumns();
$pattern = "/^{$prefix}\./";
return count(preg_grep($pattern, $columns)) > 0;
}
/**
* Returns true if the report uses the column anywhere in the query.
*
* @param string|array $column
*/
public function usesColumn($column): bool
{
return $this->hasColumn($column) || $this->hasFilter($column);
}
/**
* Returns true if the report uses the prefix anywhere in the query.
*/
public function usesColumnWithPrefix(string $prefix): bool
{
if ($this->hasColumnWithPrefix($prefix)) {
return true;
}
$this->buildSortedFilters();
$pattern = "/^{$prefix}\./";
return count(preg_grep($pattern, array_keys($this->sortedFilters))) > 0;
}
/**
* Check if the report has a specific column.
*
* @param array|string $column
*/
public function hasColumn($column): bool
{
$columns = $this->getReport()->getSelectAndAggregatorAndOrderAndGroupByColumns();
if (is_array($column)) {
foreach ($column as $checkMe) {
if (in_array($checkMe, $columns, true)) {
return true;
}
}
return false;
}
return in_array($column, $columns, true);
}
/**
* Check if the report has a specific filter.
*
* @param array|string $column
*/
public function hasFilter($column): bool
{
$this->buildSortedFilters();
if (is_array($column)) {
foreach ($column as $checkMe) {
if (isset($this->sortedFilters[$checkMe])) {
return true;
}
}
return false;
}
return isset($this->sortedFilters[$column]);
}
/**
* Get filter value from a specific filter.
*
* @param string $column
*
* @return mixed
*
* @throws \UnexpectedValueException
*/
public function getFilterValue($column)
{
return $this->getReport()->getFilterValue($column);
}
/**
* Get filter values from a specific filter.
*
* @param string $column
*
* @throws \UnexpectedValueException
*/
public function getFilterValues($column): array
{
return $this->getReport()->getFilterValues($column);
}
/**
* Check if the report has a groupBy columns selected.
*/
public function hasGroupBy(): bool
{
if (!empty($this->getReport()->getGroupBy())) {
return true;
}
return false;
}
public function createParameterName(): string
{
$alpha_numeric = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
return substr(str_shuffle($alpha_numeric), 0, 8);
}
private function buildSortedFilters(): void
{
if (null !== $this->sortedFilters) {
return;
}
$this->sortedFilters = [];
$filters = (array) $this->getReport()->getFilters();
foreach ($filters as $field) {
$this->sortedFilters[$field['column']] = true;
}
}
private function setDateRangeQueryFilters(QueryBuilder $queryBuilder, string $tablePrefix, bool $dateOnly, string $dateColumn, string $dateOnlyFilter, string $dateTimeFilter): void
{
if ($tablePrefix) {
$tablePrefix .= '.';
}
if (empty($this->options['dateFrom'])) {
$this->options['dateFrom'] = new \DateTime();
$this->options['dateFrom']->modify('-30 days');
}
if (empty($this->options['dateTo'])) {
$this->options['dateTo'] = new \DateTime();
}
if ($dateOnly) {
$queryBuilder->andWhere(sprintf($dateOnlyFilter, $tablePrefix.$dateColumn));
$queryBuilder->setParameter('dateFrom', $this->options['dateFrom']->format('Y-m-d'));
$queryBuilder->setParameter('dateTo', $this->options['dateTo']->format('Y-m-d'));
} else {
$queryBuilder->andWhere(sprintf($dateTimeFilter, $tablePrefix.$dateColumn));
$queryBuilder->setParameter('dateFrom', $this->options['dateFrom']->format('Y-m-d H:i:s'));
$queryBuilder->setParameter('dateTo', $this->options['dateTo']->format('Y-m-d H:i:s'));
}
}
private function isJoined(QueryBuilder $query, string $table, string $fromAlias, string $alias): bool
{
$queryParts = $query->getQueryParts();
$joins = !empty($queryParts) && $queryParts['join'] ? $queryParts['join'] : null;
if (empty($joins) || (!empty($joins) && empty($joins[$fromAlias]))) { // @phpstan-ignore-line
return false;
}
foreach ($joins[$fromAlias] as $join) {
if ($join['joinTable'] == $table && $join['joinAlias'] == $alias) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace Mautic\ReportBundle\Event;
use Doctrine\DBAL\Query\QueryBuilder;
use Mautic\ReportBundle\Entity\Report;
class ReportGraphEvent extends AbstractReportEvent
{
/**
* @param mixed[] $requestedGraphs
*/
public function __construct(
Report $report,
private array $requestedGraphs,
private QueryBuilder $queryBuilder,
) {
$this->report = $report;
$this->context = $report->getSource();
}
/**
* Fetch the graphs.
*
* @return array
*/
public function getGraphs()
{
return $this->requestedGraphs;
}
/**
* Set the graph array.
*
* @param string $graph
* @param array $data prepared for this chart
*/
public function setGraph($graph, $data): void
{
if (!isset($this->requestedGraphs[$graph]['data'])) {
$this->requestedGraphs[$graph]['data'] = [];
}
$this->requestedGraphs[$graph]['data'] = $data;
}
/**
* Fetch the options array for the graph.
*
* @return array
*/
public function getOptions($graph)
{
return $this->requestedGraphs[$graph]['options'] ?? [];
}
/**
* Set an option for the graph.
*
* @param string $graph
* @param string $key
* @param string $value
*/
public function setOption($graph, $key, $value): void
{
if (!isset($this->requestedGraphs[$graph]['options'])) {
$this->requestedGraphs[$graph]['options'] = [];
}
$this->requestedGraphs[$graph]['options'][$key] = $value;
}
/**
* Set the options for a graph.
*
* @param string $graph
* @param array $options
*/
public function setOptions($graph, $options): void
{
$this->requestedGraphs[$graph]['options'] = $options;
}
/**
* Get graphs that are requested.
*/
public function getRequestedGraphs(): array
{
return array_keys($this->requestedGraphs);
}
/**
* @return QueryBuilder
*/
public function getQueryBuilder()
{
return $this->queryBuilder;
}
public function setQueryBuilder(QueryBuilder $queryBuilder): void
{
$this->queryBuilder = $queryBuilder;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Mautic\ReportBundle\Event;
use Doctrine\DBAL\Query\QueryBuilder;
use Mautic\ReportBundle\Entity\Report;
class ReportQueryEvent extends AbstractReportEvent
{
private int $totalResults;
public function __construct(
Report $report,
private QueryBuilder $query,
$totalResults,
private array $options,
) {
$this->context = $report->getSource();
$this->report = $report;
$this->totalResults = (int) $totalResults;
}
/**
* @return QueryBuilder
*/
public function getQuery()
{
return $this->query;
}
/**
* @param QueryBuilder $query
*/
public function setQuery($query): void
{
$this->query = $query;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
public function getTotalResults(): int
{
return $this->totalResults;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Mautic\ReportBundle\Event;
use Mautic\ReportBundle\Entity\Scheduler;
use Symfony\Contracts\EventDispatcher\Event;
class ReportScheduleSendEvent extends Event
{
/**
* @param string $file
*/
public function __construct(
private Scheduler $scheduler,
private $file,
) {
}
/**
* @return Scheduler
*/
public function getScheduler()
{
return $this->scheduler;
}
/**
* @return string
*/
public function getFile()
{
return $this->file;
}
}