Spaces:
No application file
No application file
| namespace Mautic\DashboardBundle\Model; | |
| use Doctrine\ORM\EntityManagerInterface; | |
| use Mautic\CoreBundle\Helper\CacheStorageHelper; | |
| use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
| use Mautic\CoreBundle\Helper\Filesystem; | |
| use Mautic\CoreBundle\Helper\InputHelper; | |
| use Mautic\CoreBundle\Helper\PathsHelper; | |
| use Mautic\CoreBundle\Helper\UserHelper; | |
| use Mautic\CoreBundle\Model\FormModel; | |
| use Mautic\CoreBundle\Security\Permissions\CorePermissions; | |
| use Mautic\CoreBundle\Translation\Translator; | |
| use Mautic\DashboardBundle\DashboardEvents; | |
| use Mautic\DashboardBundle\Entity\Widget; | |
| use Mautic\DashboardBundle\Entity\WidgetRepository; | |
| use Mautic\DashboardBundle\Factory\WidgetDetailEventFactory; | |
| use Mautic\DashboardBundle\Form\Type\WidgetType; | |
| use Psr\Log\LoggerInterface; | |
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
| use Symfony\Component\Filesystem\Exception\IOException; | |
| use Symfony\Component\Form\FormFactoryInterface; | |
| use Symfony\Component\HttpFoundation\RequestStack; | |
| use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; | |
| use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
| /** | |
| * @extends FormModel<Widget> | |
| */ | |
| class DashboardModel extends FormModel | |
| { | |
| public function __construct( | |
| CoreParametersHelper $coreParametersHelper, | |
| private PathsHelper $pathsHelper, | |
| private WidgetDetailEventFactory $widgetEventFactory, | |
| private Filesystem $filesystem, | |
| private RequestStack $requestStack, | |
| EntityManagerInterface $em, | |
| CorePermissions $security, | |
| EventDispatcherInterface $dispatcher, | |
| UrlGeneratorInterface $router, | |
| Translator $translator, | |
| UserHelper $userHelper, | |
| LoggerInterface $mauticLogger | |
| ) { | |
| parent::__construct($em, $security, $dispatcher, $router, $translator, $userHelper, $mauticLogger, $coreParametersHelper); | |
| } | |
| public function getRepository(): WidgetRepository | |
| { | |
| return $this->em->getRepository(Widget::class); | |
| } | |
| public function getPermissionBase(): string | |
| { | |
| return 'dashboard:widgets'; | |
| } | |
| /** | |
| * Get a specific entity or generate a new one if id is empty. | |
| */ | |
| public function getEntity($id = null): ?Widget | |
| { | |
| if (null === $id) { | |
| return new Widget(); | |
| } | |
| return parent::getEntity($id); | |
| } | |
| /** | |
| * Load widgets for the current user from database. | |
| * | |
| * @param bool $ignorePaginator | |
| * | |
| * @return array | |
| */ | |
| public function getWidgets($ignorePaginator = false) | |
| { | |
| return $this->getEntities([ | |
| 'orderBy' => 'w.ordering', | |
| 'filter' => [ | |
| 'force' => [ | |
| [ | |
| 'column' => 'w.createdBy', | |
| 'expr' => 'eq', | |
| 'value' => $this->userHelper->getUser()->getId(), | |
| ], | |
| ], | |
| ], | |
| 'ignore_paginator' => $ignorePaginator, | |
| ]); | |
| } | |
| /** | |
| * Creates an array that represents the dashboard and all its widgets. | |
| * Useful for dashboard exports. | |
| * | |
| * @param string $name | |
| */ | |
| public function toArray($name): array | |
| { | |
| return [ | |
| 'name' => $name, | |
| 'description' => $this->generateDescription(), | |
| 'widgets' => array_map( | |
| fn ($widget) => $widget->toArray(), | |
| $this->getWidgets(true) | |
| ), | |
| ]; | |
| } | |
| /** | |
| * Saves the dashboard snapshot to the user folder. | |
| * | |
| * @param string $name | |
| * | |
| * @throws IOException | |
| */ | |
| public function saveSnapshot($name): void | |
| { | |
| $dir = $this->pathsHelper->getSystemPath('dashboard.user'); | |
| $filename = InputHelper::filename($name, 'json'); | |
| $path = $dir.'/'.$filename; | |
| $this->filesystem->dumpFile($path, json_encode($this->toArray($name))); | |
| } | |
| /** | |
| * Generates a translatable description for a dashboard. | |
| */ | |
| public function generateDescription(): string | |
| { | |
| return $this->translator->trans( | |
| 'mautic.dashboard.generated_by', | |
| [ | |
| '%name%' => $this->userHelper->getUser()->getName(), | |
| '%date%' => (new \DateTime())->format('Y-m-d H:i:s'), | |
| ] | |
| ); | |
| } | |
| /** | |
| * Fill widgets with their empty content. | |
| * | |
| * @param array<mixed> $widgets | |
| */ | |
| public function populateWidgetPreviews(&$widgets): void | |
| { | |
| if (count($widgets)) { | |
| foreach ($widgets as &$widget) { | |
| $this->populateWidgetPreview($widget); | |
| } | |
| } | |
| } | |
| /** | |
| * Fill widgets with their content. | |
| * | |
| * @param array $widgets | |
| * @param array $filter | |
| */ | |
| public function populateWidgetsContent(&$widgets, $filter = []): void | |
| { | |
| if (count($widgets)) { | |
| foreach ($widgets as &$widget) { | |
| if (!($widget instanceof Widget)) { | |
| $widget = $this->populateWidgetEntity($widget); | |
| } | |
| $this->populateWidgetContent($widget, $filter); | |
| } | |
| } | |
| } | |
| /** | |
| * Creates a new Widget object from an array data. | |
| */ | |
| public function populateWidgetEntity(array $data): Widget | |
| { | |
| $entity = new Widget(); | |
| foreach ($data as $property => $value) { | |
| $method = 'set'.ucfirst($property); | |
| if (method_exists($entity, $method)) { | |
| $entity->$method($value); | |
| } | |
| unset($data[$property]); | |
| } | |
| return $entity; | |
| } | |
| /** | |
| * Populate widget preview. | |
| */ | |
| public function populateWidgetPreview(Widget $widget): void | |
| { | |
| $event = $this->widgetEventFactory->create($widget); | |
| $this->dispatcher->dispatch($event, DashboardEvents::DASHBOARD_ON_MODULE_DETAIL_PRE_LOAD); | |
| } | |
| /** | |
| * Load widget content from the onWidgetDetailGenerate event. | |
| * | |
| * @param array $filter | |
| */ | |
| public function populateWidgetContent(Widget $widget, $filter = []): void | |
| { | |
| if (null === $widget->getCacheTimeout() || -1 === $widget->getCacheTimeout()) { | |
| $widget->setCacheTimeout($this->coreParametersHelper->get('cached_data_timeout')); | |
| } | |
| // Merge global filter with widget params | |
| $widgetParams = $widget->getParams(); | |
| $resultParams = array_merge($widgetParams, $filter); | |
| // Add the user timezone | |
| if (empty($resultParams['timezone'])) { | |
| $resultParams['timezone'] = $this->userHelper->getUser()->getTimezone(); | |
| } | |
| // Clone the objects in param array to avoid reference issues if some subscriber changes them | |
| foreach ($resultParams as &$param) { | |
| if (is_object($param)) { | |
| $param = clone $param; | |
| } | |
| } | |
| $widget->setParams($resultParams); | |
| $this->dispatcher->dispatch( | |
| $this->widgetEventFactory->create($widget), | |
| DashboardEvents::DASHBOARD_ON_MODULE_DETAIL_GENERATE | |
| ); | |
| } | |
| /** | |
| * Clears the temporary widget cache. | |
| */ | |
| public function clearDashboardCache(): void | |
| { | |
| $cacheDir = $this->coreParametersHelper->get('cached_data_dir', $this->pathsHelper->getSystemPath('cache', true)); | |
| $cacheStorage = new CacheStorageHelper(CacheStorageHelper::ADAPTOR_FILESYSTEM, $this->userHelper->getUser()->getId(), null, $cacheDir); | |
| $cacheStorage->clear(); | |
| } | |
| /** | |
| * @param Widget $entity | |
| * @param string|null $action | |
| * @param array $options | |
| * | |
| * @return \Symfony\Component\Form\FormInterface<mixed> | |
| * | |
| * @throws MethodNotAllowedHttpException | |
| */ | |
| public function createForm($entity, FormFactoryInterface $formFactory, $action = null, $options = []): \Symfony\Component\Form\FormInterface | |
| { | |
| if (!$entity instanceof Widget) { | |
| throw new MethodNotAllowedHttpException(['Widget'], 'Entity must be of class Widget()'); | |
| } | |
| if (!empty($action)) { | |
| $options['action'] = $action; | |
| } | |
| return $formFactory->create(WidgetType::class, $entity, $options); | |
| } | |
| /** | |
| * Create/edit entity. | |
| * | |
| * @param object $entity | |
| * @param bool $unlock | |
| * | |
| * @throws \Exception | |
| */ | |
| public function saveEntity($entity, $unlock = true): void | |
| { | |
| // Set widget name from widget type if empty | |
| if (!$entity->getName()) { | |
| $entity->setName($this->translator->trans('mautic.widget.'.$entity->getType())); | |
| } | |
| $entity->setDateModified(new \DateTime()); | |
| parent::saveEntity($entity, $unlock); | |
| } | |
| /** | |
| * Generate default date range filter and time unit. | |
| */ | |
| public function getDefaultFilter(): array | |
| { | |
| $dateRangeDefault = $this->coreParametersHelper->get('default_daterange_filter', '-1 month'); | |
| $dateRangeStart = new \DateTime(); | |
| $dateRangeStart->modify($dateRangeDefault); | |
| $session = $this->requestStack->getSession(); | |
| $today = new \DateTime(); | |
| $dateFrom = new \DateTime($session->get('mautic.daterange.form.from', $dateRangeStart->format('Y-m-d 00:00:00'))); | |
| $dateTo = new \DateTime($session->get('mautic.daterange.form.to', $today->format('Y-m-d 23:59:59'))); | |
| return [ | |
| 'dateFrom' => $dateFrom, | |
| 'dateTo' => $dateTo->modify('23:59:59'), // till end of the 'to' date selected | |
| ]; | |
| } | |
| } | |