Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,390 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\DashboardBundle\Event;
|
||||
|
||||
use Mautic\CacheBundle\Cache\CacheProviderTagAwareInterface;
|
||||
use Mautic\CoreBundle\Event\CommonEvent;
|
||||
use Mautic\CoreBundle\Helper\CacheStorageHelper;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\DashboardBundle\Entity\Widget;
|
||||
use Mautic\DashboardBundle\Exception\CouldNotFormatDateTimeException;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class WidgetDetailEvent extends CommonEvent
|
||||
{
|
||||
public const DASHBOARD_CACHE_TAG = 'dashboard_widget';
|
||||
|
||||
protected $type;
|
||||
|
||||
protected $template;
|
||||
|
||||
protected $templateData = [];
|
||||
|
||||
protected $errorMessage;
|
||||
|
||||
protected $uniqueId;
|
||||
|
||||
protected $cacheDir;
|
||||
|
||||
protected $uniqueCacheDir;
|
||||
|
||||
protected $cacheTimeout;
|
||||
|
||||
protected float $startTime;
|
||||
|
||||
protected $loadTime = 0;
|
||||
|
||||
private string $cacheKeyPath = 'dashboard.widget.';
|
||||
|
||||
private bool $isPreview = false;
|
||||
|
||||
public function __construct(private TranslatorInterface $translator, private CorePermissions $security, protected Widget $widget, private ?CacheProviderTagAwareInterface $cacheProvider = null)
|
||||
{
|
||||
$this->startTime = microtime(true);
|
||||
$this->setWidget($widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* Act as widget preview without data.
|
||||
*/
|
||||
public function setPreview(bool $isPreview): void
|
||||
{
|
||||
$this->isPreview = $isPreview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is preview without data?
|
||||
*/
|
||||
public function isPreview(): bool
|
||||
{
|
||||
return $this->isPreview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return unique key, uses legacy methods for BC.
|
||||
*/
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
$cacheKey = [
|
||||
$this->getUniqueWidgetId(),
|
||||
];
|
||||
|
||||
$params = $this->getWidget()->getParams();
|
||||
|
||||
foreach (['dateTo', 'dateFrom'] as $dateParameter) {
|
||||
if (isset($params[$dateParameter])) {
|
||||
try {
|
||||
$date = $this->castDateTimeToString($params[$dateParameter]);
|
||||
$cacheKey[] = $date;
|
||||
} catch (CouldNotFormatDateTimeException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no additional parameters we return uniqueWidgetId as a cache key
|
||||
// Otherwise we return hashed $cacheKey value
|
||||
$cacheKey = (1 == count($cacheKey)) ? $this->getUniqueWidgetId() : substr(md5(implode('', $cacheKey)), 0, 16);
|
||||
|
||||
return $this->cacheKeyPath.$cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cache dir.
|
||||
*
|
||||
* @param string $cacheDir
|
||||
* @param mixed|null $uniqueCacheDir
|
||||
*/
|
||||
public function setCacheDir($cacheDir, $uniqueCacheDir = null): void
|
||||
{
|
||||
$this->cacheDir = $cacheDir;
|
||||
$this->uniqueCacheDir = $uniqueCacheDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cache timeout.
|
||||
*
|
||||
* @param string $cacheTimeout
|
||||
*/
|
||||
public function setCacheTimeout($cacheTimeout): void
|
||||
{
|
||||
$this->cacheTimeout = (int) $cacheTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the widget type.
|
||||
*
|
||||
* @param string $type
|
||||
*/
|
||||
public function setType($type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the widget type.
|
||||
*
|
||||
* @return string $type
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the widget entity.
|
||||
*/
|
||||
public function setWidget(Widget $widget): void
|
||||
{
|
||||
$this->widget = $widget;
|
||||
|
||||
$params = $widget->getParams();
|
||||
|
||||
// Set required params if undefined
|
||||
if (!isset($params['timeUnit'])) {
|
||||
$params['timeUnit'] = null;
|
||||
}
|
||||
|
||||
if (!isset($params['amount'])) {
|
||||
$params['amount'] = null;
|
||||
}
|
||||
|
||||
if (!isset($params['dateFormat'])) {
|
||||
$params['dateFormat'] = null;
|
||||
}
|
||||
|
||||
if (!isset($params['filter'])) {
|
||||
$params['filter'] = [];
|
||||
}
|
||||
|
||||
$widget->setParams($params);
|
||||
|
||||
$this->setType($widget->getType());
|
||||
$this->setCacheTimeout($widget->getCacheTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the widget entity.
|
||||
*
|
||||
* @return Widget $widget
|
||||
*/
|
||||
public function getWidget()
|
||||
{
|
||||
return $this->widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the widget template.
|
||||
*
|
||||
* @param string $template
|
||||
*/
|
||||
public function setTemplate($template): void
|
||||
{
|
||||
$this->template = $template;
|
||||
$this->widget->setTemplate($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the widget template.
|
||||
*
|
||||
* @return string $template
|
||||
*/
|
||||
public function getTemplate()
|
||||
{
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the widget template data.
|
||||
*
|
||||
* @param bool|null $skipCache
|
||||
*
|
||||
* @throws \Psr\Cache\InvalidArgumentException
|
||||
*/
|
||||
public function setTemplateData(array $templateData, $skipCache = false): void
|
||||
{
|
||||
$this->templateData = $templateData;
|
||||
$this->widget->setTemplateData($templateData);
|
||||
$this->widget->setLoadTime(abs(microtime(true) - $this->startTime));
|
||||
|
||||
if ($this->usesLegacyCache()) {
|
||||
// Store the template data to the cache
|
||||
if (!$skipCache && $this->cacheDir && $this->widget->getCacheTimeout() > 0) {
|
||||
$cache = new CacheStorageHelper(CacheStorageHelper::ADAPTOR_FILESYSTEM, $this->uniqueCacheDir, null, $this->cacheDir);
|
||||
// must pass a DateTime object or a int of seconds to expire as 3rd attribute to set().
|
||||
$expireTime = $this->widget->getCacheTimeout() * 60;
|
||||
|
||||
$cache->set($this->getUniqueWidgetId(), $templateData, (int) $expireTime);
|
||||
}
|
||||
}
|
||||
|
||||
$cItem = $this->cacheProvider->getItem($this->getCacheKey());
|
||||
if ($this->widget->getCacheTimeout()) {
|
||||
$cItem->expiresAfter((int) $this->widget->getCacheTimeout() * 60); // This is in minutes
|
||||
}
|
||||
$cItem->set($templateData);
|
||||
$cItem->tag(self::DASHBOARD_CACHE_TAG);
|
||||
|
||||
$this->cacheProvider->save($cItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the widget template data.
|
||||
*
|
||||
* @return array<mixed> $templateData
|
||||
*/
|
||||
public function getTemplateData()
|
||||
{
|
||||
return $this->templateData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set en error message.
|
||||
*
|
||||
* @param string $errorMessage
|
||||
*/
|
||||
public function setErrorMessage($errorMessage): void
|
||||
{
|
||||
$this->errorMessage = $errorMessage;
|
||||
$this->widget->setErrorMessage($errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an error message.
|
||||
*
|
||||
* @return string $errorMessage
|
||||
*/
|
||||
public function getErrorMessage()
|
||||
{
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a unique ID from type and widget params.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUniqueWidgetId()
|
||||
{
|
||||
if ($this->uniqueId) {
|
||||
return $this->uniqueId;
|
||||
}
|
||||
|
||||
$params = $this->getWidget()->getParams();
|
||||
// Unset dateFrom and dateTo since they constantly change
|
||||
unset($params['dateFrom'], $params['dateTo']);
|
||||
|
||||
$uniqueSettings = [
|
||||
'params' => $params,
|
||||
'width' => $this->getWidget()->getWidth(),
|
||||
'height' => $this->getWidget()->getHeight(),
|
||||
'locale' => $this->translator->getLocale(),
|
||||
];
|
||||
|
||||
return $this->uniqueId = $this->getType().'_'.substr(md5(json_encode($uniqueSettings)), 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Psr\Cache\InvalidArgumentException
|
||||
* Checks the cache for the widget data.
|
||||
* If cache exists, it sets the TemplateData.
|
||||
*/
|
||||
public function isCached(): bool
|
||||
{
|
||||
if (!$this->cacheDir && $this->usesLegacyCache()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->usesLegacyCache()) {
|
||||
$cache = new CacheStorageHelper(CacheStorageHelper::ADAPTOR_FILESYSTEM, $this->uniqueCacheDir, null, $this->cacheDir);
|
||||
$data = $cache->get($this->getUniqueWidgetId(), $this->cacheTimeout);
|
||||
|
||||
if ($data) {
|
||||
$this->widget->setCached(true);
|
||||
$this->setTemplateData($data, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
$cachedItem = $this->cacheProvider->getItem($this->getCacheKey());
|
||||
if (!$cachedItem->isHit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->widget->setCached(true);
|
||||
$this->setTemplateData($cachedItem->get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Translator object.
|
||||
*
|
||||
* @return TranslatorInterface
|
||||
*/
|
||||
public function getTranslator()
|
||||
{
|
||||
return $this->translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has at least one permission of defined array of permissions.
|
||||
*/
|
||||
public function hasPermissions(array $permissions): bool
|
||||
{
|
||||
if (!$this->security) {
|
||||
return true;
|
||||
}
|
||||
$perm = $this->security->isGranted($permissions, 'RETURN_ARRAY');
|
||||
|
||||
return in_array(true, $perm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has defined permission to see the widgets.
|
||||
*
|
||||
* @param string $permission
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPermission($permission)
|
||||
{
|
||||
if (!$this->security) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->security->isGranted($permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for cache type. This event should be created by factory thus not legacy approach.
|
||||
*/
|
||||
private function usesLegacyCache(): bool
|
||||
{
|
||||
return is_null($this->cacheProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to cast DateTime objects to strings to use them in the cache key.
|
||||
*
|
||||
* @param mixed|null $value
|
||||
*
|
||||
* @throws CouldNotFormatDateTimeException
|
||||
*/
|
||||
private function castDateTimeToString($value): string
|
||||
{
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
// We use RFC 2822 format because it includes timezone
|
||||
return $value->format('r');
|
||||
}
|
||||
|
||||
try {
|
||||
$value = strval($value);
|
||||
} catch (\Exception) {
|
||||
throw new CouldNotFormatDateTimeException();
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\DashboardBundle\Event;
|
||||
|
||||
use Mautic\CoreBundle\Event\CommonEvent;
|
||||
use Mautic\DashboardBundle\Entity\Widget;
|
||||
|
||||
class WidgetFormEvent extends CommonEvent
|
||||
{
|
||||
protected $form;
|
||||
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Set the widget type.
|
||||
*
|
||||
* @param string $type
|
||||
*/
|
||||
public function setType($type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the widget type.
|
||||
*
|
||||
* @return string $type
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the widget form.
|
||||
*
|
||||
* @param string $form
|
||||
*/
|
||||
public function setForm($form): void
|
||||
{
|
||||
$this->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the widget edit form.
|
||||
*/
|
||||
public function getForm()
|
||||
{
|
||||
return $this->form;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\DashboardBundle\Event;
|
||||
|
||||
use Mautic\CoreBundle\Event\CommonEvent;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\DashboardBundle\Entity\Widget;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class WidgetTypeListEvent extends CommonEvent
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $widgetTypes = [];
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
/**
|
||||
* @var CorePermissions
|
||||
*/
|
||||
protected $security;
|
||||
|
||||
/**
|
||||
* Adds a new widget type to the widget types list.
|
||||
*
|
||||
* @param string $widgetType
|
||||
* @param string $bundle name (widget category)
|
||||
*/
|
||||
public function addType($widgetType, $bundle = 'others'): void
|
||||
{
|
||||
$bundle = 'mautic.'.$bundle.'.dashboard.widgets';
|
||||
$widgetTypeName = 'mautic.widget.'.$widgetType;
|
||||
|
||||
if ($this->translator) {
|
||||
$bundle = $this->translator->trans($bundle);
|
||||
$widgetTypeName = $this->translator->trans($widgetTypeName);
|
||||
}
|
||||
|
||||
if (!isset($this->widgetTypes[$bundle])) {
|
||||
$this->widgetTypes[$bundle] = [];
|
||||
}
|
||||
|
||||
$this->widgetTypes[$bundle][$widgetType] = $widgetTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set translator if you want the strings to be translated.
|
||||
*/
|
||||
public function setTranslator(TranslatorInterface $translator): void
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set security object to check the perimissions.
|
||||
*/
|
||||
public function setSecurity(CorePermissions $security): void
|
||||
{
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has permission to see the widgets.
|
||||
*/
|
||||
public function hasPermissions(array $permissions): bool
|
||||
{
|
||||
if (!$this->security) {
|
||||
return true;
|
||||
}
|
||||
$perm = $this->security->isGranted($permissions, 'RETURN_ARRAY');
|
||||
|
||||
return !in_array(false, $perm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of widget types.
|
||||
*
|
||||
* @return array $widgetTypes
|
||||
*/
|
||||
public function getTypes()
|
||||
{
|
||||
return $this->widgetTypes;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user