Issues (3627)

app/bundles/AssetBundle/Model/AssetModel.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2014 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\AssetBundle\Model;
13
14
use Doctrine\ORM\PersistentCollection;
15
use Mautic\AssetBundle\AssetEvents;
16
use Mautic\AssetBundle\Entity\Asset;
17
use Mautic\AssetBundle\Entity\Download;
18
use Mautic\AssetBundle\Event\AssetEvent;
19
use Mautic\AssetBundle\Event\AssetLoadEvent;
20
use Mautic\AssetBundle\Form\Type\AssetType;
21
use Mautic\CategoryBundle\Model\CategoryModel;
22
use Mautic\CoreBundle\Helper\Chart\ChartQuery;
23
use Mautic\CoreBundle\Helper\Chart\LineChart;
24
use Mautic\CoreBundle\Helper\Chart\PieChart;
25
use Mautic\CoreBundle\Helper\CoreParametersHelper;
26
use Mautic\CoreBundle\Helper\FileHelper;
27
use Mautic\CoreBundle\Helper\IpLookupHelper;
28
use Mautic\CoreBundle\Model\FormModel;
29
use Mautic\EmailBundle\Entity\Email;
30
use Mautic\LeadBundle\Entity\Lead;
31
use Mautic\LeadBundle\Model\LeadModel;
32
use Mautic\LeadBundle\Tracker\ContactTracker;
33
use Mautic\LeadBundle\Tracker\Factory\DeviceDetectorFactory\DeviceDetectorFactoryInterface;
34
use Mautic\LeadBundle\Tracker\Service\DeviceCreatorService\DeviceCreatorServiceInterface;
35
use Mautic\LeadBundle\Tracker\Service\DeviceTrackingService\DeviceTrackingServiceInterface;
36
use Symfony\Component\EventDispatcher\Event;
37
use Symfony\Component\HttpFoundation\RequestStack;
38
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
39
40
class AssetModel extends FormModel
41
{
42
    /**
43
     * @var CategoryModel
44
     */
45
    protected $categoryModel;
46
47
    /**
48
     * @var LeadModel
49
     */
50
    protected $leadModel;
51
52
    /**
53
     * @var \Symfony\Component\HttpFoundation\Request|null
54
     */
55
    protected $request;
56
57
    /**
58
     * @var IpLookupHelper
59
     */
60
    protected $ipLookupHelper;
61
62
    /**
63
     * @var int
64
     */
65
    protected $maxAssetSize;
66
67
    /**
68
     * @var DeviceCreatorServiceInterface
69
     */
70
    private $deviceCreatorService;
71
72
    /**
73
     * @var DeviceDetectorFactoryInterface
74
     */
75
    private $deviceDetectorFactory;
76
77
    /**
78
     * @var DeviceTrackingServiceInterface
79
     */
80
    private $deviceTrackingService;
81
82
    /**
83
     * @var ContactTracker
84
     */
85
    private $contactTracker;
86
87
    /**
88
     * AssetModel constructor.
89
     */
90
    public function __construct(
91
        LeadModel $leadModel,
92
        CategoryModel $categoryModel,
93
        RequestStack $requestStack,
94
        IpLookupHelper $ipLookupHelper,
95
        CoreParametersHelper $coreParametersHelper,
96
        DeviceCreatorServiceInterface $deviceCreatorService,
97
        DeviceDetectorFactoryInterface $deviceDetectorFactory,
98
        DeviceTrackingServiceInterface $deviceTrackingService,
99
        ContactTracker $contactTracker
100
    ) {
101
        $this->leadModel              = $leadModel;
102
        $this->categoryModel          = $categoryModel;
103
        $this->request                = $requestStack->getCurrentRequest();
104
        $this->ipLookupHelper         = $ipLookupHelper;
105
        $this->deviceCreatorService   = $deviceCreatorService;
106
        $this->deviceDetectorFactory  = $deviceDetectorFactory;
107
        $this->deviceTrackingService  = $deviceTrackingService;
108
        $this->contactTracker         = $contactTracker;
109
        $this->maxAssetSize           = $coreParametersHelper->get('max_size');
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function saveEntity($entity, $unlock = true)
116
    {
117
        if (empty($this->inConversion)) {
118
            $alias = $entity->getAlias();
119
            if (empty($alias)) {
120
                $alias = $entity->getTitle();
121
            }
122
            $alias = $this->cleanAlias($alias, '', false, '-');
123
124
            //make sure alias is not already taken
125
            $repo      = $this->getRepository();
126
            $testAlias = $alias;
127
            $count     = $repo->checkUniqueAlias($testAlias, $entity);
128
            $aliasTag  = $count;
129
130
            while ($count) {
131
                $testAlias = $alias.$aliasTag;
132
                $count     = $repo->checkUniqueAlias($testAlias, $entity);
133
                ++$aliasTag;
134
            }
135
            if ($testAlias != $alias) {
136
                $alias = $testAlias;
137
            }
138
            $entity->setAlias($alias);
139
        }
140
141
        if (!$entity->isNew()) {
142
            //increase the revision
143
            $revision = $entity->getRevision();
144
            ++$revision;
145
            $entity->setRevision($revision);
146
        }
147
148
        parent::saveEntity($entity, $unlock);
149
    }
150
151
    /**
152
     * @param $asset
153
     * @param null   $request
154
     * @param string $code
155
     * @param array  $systemEntry
156
     *
157
     * @throws \Doctrine\ORM\ORMException
158
     * @throws \Exception
159
     */
160
    public function trackDownload($asset, $request = null, $code = '200', $systemEntry = [])
161
    {
162
        // Don't skew results with in-house downloads
163
        if (empty($systemEntry) && !$this->security->isAnonymous()) {
164
            return;
165
        }
166
167
        if (null == $request) {
168
            $request = $this->request;
169
        }
170
171
        $download = new Download();
172
        $download->setDateDownload(new \Datetime());
173
174
        // Download triggered by lead
175
        if (empty($systemEntry)) {
176
            //check for any clickthrough info
177
            $clickthrough = $request->get('ct', false);
178
            if (!empty($clickthrough)) {
179
                $clickthrough = $this->decodeArrayFromUrl($clickthrough);
180
181
                if (!empty($clickthrough['lead'])) {
182
                    $lead = $this->leadModel->getEntity($clickthrough['lead']);
183
                    if (null !== $lead) {
184
                        $wasTrackedAlready                    = $this->deviceTrackingService->isTracked();
185
                        $deviceDetector                       = $this->deviceDetectorFactory->create($request->server->get('HTTP_USER_AGENT'));
186
                        $deviceDetector->parse();
187
                        $currentDevice                             = $this->deviceCreatorService->getCurrentFromDetector($deviceDetector, $lead);
188
                        $trackedDevice                             = $this->deviceTrackingService->trackCurrentDevice($currentDevice, false);
0 ignored issues
show
It seems like $currentDevice can also be of type null; however, parameter $device of Mautic\LeadBundle\Tracke...e::trackCurrentDevice() does only seem to accept Mautic\LeadBundle\Entity\LeadDevice, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
                        $trackedDevice                             = $this->deviceTrackingService->trackCurrentDevice(/** @scrutinizer ignore-type */ $currentDevice, false);
Loading history...
189
                        $trackingId                                = $trackedDevice->getTrackingId();
190
                        $trackingNewlyGenerated                    = !$wasTrackedAlready;
191
                        $leadClickthrough                          = true;
192
193
                        $this->contactTracker->setTrackedContact($lead);
194
                    }
195
                }
196
                if (!empty($clickthrough['channel'])) {
197
                    if (1 === count($clickthrough['channel'])) {
198
                        $channelId = reset($clickthrough['channel']);
199
                        $channel   = key($clickthrough['channel']);
200
                    } else {
201
                        $channel   = $clickthrough['channel'][0];
202
                        $channelId = (int) $clickthrough['channel'][1];
203
                    }
204
                    $download->setSource($channel);
205
                    $download->setSourceId($channelId);
206
                } elseif (!empty($clickthrough['source'])) {
207
                    $download->setSource($clickthrough['source'][0]);
208
                    $download->setSourceId($clickthrough['source'][1]);
209
                }
210
211
                if (!empty($clickthrough['email'])) {
212
                    $emailRepo = $this->em->getRepository('MauticEmailBundle:Email');
213
                    if ($emailEntity = $emailRepo->getEntity($clickthrough['email'])) {
214
                        $download->setEmail($emailEntity);
215
                    }
216
                }
217
            }
218
219
            if (empty($leadClickthrough)) {
220
                $wasTrackedAlready         = $this->deviceTrackingService->isTracked();
221
                $lead                      = $this->contactTracker->getContact();
222
                $trackedDevice             = $this->deviceTrackingService->getTrackedDevice();
223
                $trackingId                = null;
224
                $trackingNewlyGenerated    = false;
225
                if (null !== $trackedDevice) {
226
                    $trackingId             = $trackedDevice->getTrackingId();
227
                    $trackingNewlyGenerated = !$wasTrackedAlready;
228
                }
229
            }
230
231
            $download->setLead($lead);
232
        } else {
233
            $trackingId = '';
234
235
            if (isset($systemEntry['lead'])) {
236
                $lead = $systemEntry['lead'];
237
                if (!$lead instanceof Lead) {
238
                    $leadId = is_array($lead) ? $lead['id'] : $lead;
239
                    $lead   = $this->em->getReference('MauticLeadBundle:Lead', $leadId);
240
                }
241
242
                $download->setLead($lead);
243
            }
244
245
            if (!empty($systemEntry['source'])) {
246
                $download->setSource($systemEntry['source'][0]);
247
                $download->setSourceId($systemEntry['source'][1]);
248
            }
249
250
            if (isset($systemEntry['email'])) {
251
                $email = $systemEntry['email'];
252
                if (!$email instanceof Email) {
253
                    $emailId = is_array($email) ? $email['id'] : $email;
254
                    $email   = $this->em->getReference('MauticEmailBundle:Email', $emailId);
255
                }
256
257
                $download->setEmail($email);
258
            }
259
260
            if (isset($systemEntry['tracking_id'])) {
261
                $trackingId             = $systemEntry['tracking_id'];
262
                $trackingNewlyGenerated = false;
263
            } elseif ($this->security->isAnonymous() && !defined('IN_MAUTIC_CONSOLE')) {
264
                // If the session is anonymous and not triggered via CLI, assume the lead did something to trigger the
265
                // system forced download such as an email
266
                $deviceWasTracked       = $this->deviceTrackingService->isTracked();
267
                $deviceDetector         = $this->deviceDetectorFactory->create($request->server->get('HTTP_USER_AGENT'));
268
                $deviceDetector->parse();
269
                $currentDevice          = $this->deviceCreatorService->getCurrentFromDetector($deviceDetector, $lead);
270
                $trackedDevice          = $this->deviceTrackingService->trackCurrentDevice($currentDevice, false);
271
                $trackingId             = $trackedDevice->getTrackingId();
272
                $trackingNewlyGenerated = !$deviceWasTracked;
273
            }
274
        }
275
276
        $isUnique = true;
277
        if (!empty($trackingNewlyGenerated)) {
278
            // Cookie was just generated so this is definitely a unique download
279
            $isUnique = $trackingNewlyGenerated;
280
        } elseif (!empty($trackingId)) {
281
            // Determine if this is a unique download
282
            $isUnique = $this->getDownloadRepository()->isUniqueDownload($asset->getId(), $trackingId);
283
        }
284
285
        $download->setTrackingId($trackingId);
286
287
        if (!empty($asset) && empty($systemEntry)) {
288
            $download->setAsset($asset);
289
290
            $this->getRepository()->upDownloadCount($asset->getId(), 1, $isUnique);
291
        }
292
293
        //check for existing IP
294
        $ipAddress = $this->ipLookupHelper->getIpAddress();
295
296
        $download->setCode($code);
297
        $download->setIpAddress($ipAddress);
298
299
        if (null !== $request) {
300
            $download->setReferer($request->server->get('HTTP_REFERER'));
301
        }
302
303
        // Dispatch event
304
        if ($this->dispatcher->hasListeners(AssetEvents::ASSET_ON_LOAD)) {
305
            $event = new AssetLoadEvent($download, $isUnique);
306
            $this->dispatcher->dispatch(AssetEvents::ASSET_ON_LOAD, $event);
307
        }
308
309
        // Wrap in a try/catch to prevent deadlock errors on busy servers
310
        try {
311
            $this->em->persist($download);
312
            $this->em->flush();
313
        } catch (\Exception $e) {
314
            if (MAUTIC_ENV === 'dev') {
315
                throw $e;
316
            } else {
317
                error_log($e);
318
            }
319
        }
320
321
        $this->em->detach($download);
322
    }
323
324
    /**
325
     * Increase the download count.
326
     *
327
     * @param            $asset
328
     * @param int        $increaseBy
329
     * @param bool|false $unique
330
     */
331
    public function upDownloadCount($asset, $increaseBy = 1, $unique = false)
332
    {
333
        $id = ($asset instanceof Asset) ? $asset->getId() : (int) $asset;
334
335
        $this->getRepository()->upDownloadCount($id, $increaseBy, $unique);
336
    }
337
338
    /**
339
     * @return \Mautic\AssetBundle\Entity\AssetRepository
340
     */
341
    public function getRepository()
342
    {
343
        return $this->em->getRepository('MauticAssetBundle:Asset');
344
    }
345
346
    /**
347
     * @return \Mautic\AssetBundle\Entity\DownloadRepository
348
     */
349
    public function getDownloadRepository()
350
    {
351
        return $this->em->getRepository('MauticAssetBundle:Download');
352
    }
353
354
    /**
355
     * @return string
356
     */
357
    public function getPermissionBase()
358
    {
359
        return 'asset:assets';
360
    }
361
362
    /**
363
     * @return string
364
     */
365
    public function getNameGetter()
366
    {
367
        return 'getTitle';
368
    }
369
370
    /**
371
     * {@inheritdoc}
372
     *
373
     * @throws NotFoundHttpException
374
     */
375
    public function createForm($entity, $formFactory, $action = null, $options = [])
376
    {
377
        if (!$entity instanceof Asset) {
378
            throw new MethodNotAllowedHttpException(['Asset']);
379
        }
380
381
        if (!empty($action)) {
382
            $options['action'] = $action;
383
        }
384
385
        return $formFactory->create(AssetType::class, $entity, $options);
386
    }
387
388
    /**
389
     * Get a specific entity or generate a new one if id is empty.
390
     *
391
     * @param $id
392
     *
393
     * @return Asset|null
394
     */
395
    public function getEntity($id = null)
396
    {
397
        if (null === $id) {
398
            $entity = new Asset();
399
        } else {
400
            $entity = parent::getEntity($id);
401
        }
402
403
        return $entity;
404
    }
405
406
    /**
407
     * {@inheritdoc}
408
     *
409
     * @param $action
410
     * @param $event
411
     * @param $entity
412
     * @param $isNew
413
     *
414
     * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
415
     */
416
    protected function dispatchEvent($action, &$entity, $isNew = false, Event $event = null)
417
    {
418
        if (!$entity instanceof Asset) {
419
            throw new MethodNotAllowedHttpException(['Asset']);
420
        }
421
422
        switch ($action) {
423
            case 'pre_save':
424
                $name = AssetEvents::ASSET_PRE_SAVE;
425
                break;
426
            case 'post_save':
427
                $name = AssetEvents::ASSET_POST_SAVE;
428
                break;
429
            case 'pre_delete':
430
                $name = AssetEvents::ASSET_PRE_DELETE;
431
                break;
432
            case 'post_delete':
433
                $name = AssetEvents::ASSET_POST_DELETE;
434
                break;
435
            default:
436
                return null;
437
        }
438
439
        if ($this->dispatcher->hasListeners($name)) {
440
            if (empty($event)) {
441
                $event = new AssetEvent($entity, $isNew);
442
                $event->setEntityManager($this->em);
443
            }
444
445
            $this->dispatcher->dispatch($name, $event);
446
447
            return $event;
448
        } else {
449
            return null;
450
        }
451
    }
452
453
    /**
454
     * Get list of entities for autopopulate fields.
455
     *
456
     * @param $type
457
     * @param $filter
458
     * @param $limit
459
     *
460
     * @return array
461
     */
462
    public function getLookupResults($type, $filter = '', $limit = 10)
463
    {
464
        $results = [];
465
        switch ($type) {
466
            case 'asset':
467
                $viewOther = $this->security->isGranted('asset:assets:viewother');
468
                $repo      = $this->getRepository();
469
                $repo->setCurrentUser($this->userHelper->getUser());
470
                $results = $repo->getAssetList($filter, $limit, 0, $viewOther);
471
                break;
472
            case 'category':
473
                $results = $this->categoryModel->getRepository()->getCategoryList($filter, $limit, 0);
474
                break;
475
        }
476
477
        return $results;
478
    }
479
480
    /**
481
     * Generate url for an asset.
482
     *
483
     * @param Asset $entity
484
     * @param bool  $absolute
485
     * @param array $clickthrough
486
     *
487
     * @return string
488
     */
489
    public function generateUrl($entity, $absolute = true, $clickthrough = [])
490
    {
491
        $assetSlug = $entity->getId().':'.$entity->getAlias();
492
493
        $slugs = [
494
            'slug' => $assetSlug,
495
        ];
496
497
        return $this->buildUrl('mautic_asset_download', $slugs, $absolute, $clickthrough);
498
    }
499
500
    /**
501
     * Determine the max upload size based on PHP restrictions and config.
502
     *
503
     * @param string     $unit          If '', determine the best unit based on the number
504
     * @param bool|false $humanReadable Return as a human readable filesize
505
     *
506
     * @return float
507
     */
508
    public function getMaxUploadSize($unit = 'M', $humanReadable = false)
509
    {
510
        $maxAssetSize  = $this->maxAssetSize;
511
        $maxAssetSize  = (-1 == $maxAssetSize || 0 === $maxAssetSize) ? PHP_INT_MAX : FileHelper::convertMegabytesToBytes($maxAssetSize);
512
        $maxPostSize   = Asset::getIniValue('post_max_size');
513
        $maxUploadSize = Asset::getIniValue('upload_max_filesize');
514
        $memoryLimit   = Asset::getIniValue('memory_limit');
515
        $maxAllowed    = min(array_filter([$maxAssetSize, $maxPostSize, $maxUploadSize, $memoryLimit]));
516
517
        if ($humanReadable) {
518
            $number = Asset::convertBytesToHumanReadable($maxAllowed);
519
        } else {
520
            list($number, $unit) = Asset::convertBytesToUnit($maxAllowed, $unit);
521
        }
522
523
        return $number;
524
    }
525
526
    /**
527
     * @param $assets
528
     *
529
     * @return int|string
530
     */
531
    public function getTotalFilesize($assets)
532
    {
533
        $firstAsset = is_array($assets) ? reset($assets) : false;
534
        if ($assets instanceof PersistentCollection || is_object($firstAsset)) {
535
            $assetIds = [];
536
            foreach ($assets as $asset) {
537
                $assetIds[] = $asset->getId();
538
            }
539
            $assets = $assetIds;
540
        }
541
542
        if (!is_array($assets)) {
543
            $assets = [$assets];
544
        }
545
546
        if (empty($assets)) {
547
            return 0;
548
        }
549
550
        $repo = $this->getRepository();
551
        $size = $repo->getAssetSize($assets);
552
553
        if ($size) {
554
            $size = Asset::convertBytesToHumanReadable($size);
555
        }
556
557
        return $size;
558
    }
559
560
    /**
561
     * Get line chart data of downloads.
562
     *
563
     * @param char   $unit          {@link php.net/manual/en/function.date.php#refsect1-function.date-parameters}
564
     * @param string $dateFormat
565
     * @param array  $filter
566
     * @param bool   $canViewOthers
567
     *
568
     * @return array
569
     */
570
    public function getDownloadsLineChartData($unit, \DateTime $dateFrom, \DateTime $dateTo, $dateFormat = null, $filter = [], $canViewOthers = true)
571
    {
572
        $chart = new LineChart($unit, $dateFrom, $dateTo, $dateFormat);
573
        $query = new ChartQuery($this->em->getConnection(), $dateFrom, $dateTo);
574
        $q     = $query->prepareTimeDataQuery('asset_downloads', 'date_download', $filter);
575
576
        if (!$canViewOthers) {
577
            $q->join('t', MAUTIC_TABLE_PREFIX.'assets', 'a', 'a.id = t.asset_id')
578
                ->andWhere('a.created_by = :userId')
579
                ->setParameter('userId', $this->userHelper->getUser()->getId());
580
        }
581
582
        $data = $query->loadAndBuildTimeData($q);
583
584
        $chart->setDataset($this->translator->trans('mautic.asset.downloadcount'), $data);
585
586
        return $chart->render();
587
    }
588
589
    /**
590
     * Get pie chart data of unique vs repetitive downloads.
591
     * Repetitive in this case mean if a lead downloaded any of the assets more than once.
592
     *
593
     * @param string $dateFrom
594
     * @param string $dateTo
595
     * @param array  $filters
596
     * @param bool   $canViewOthers
597
     *
598
     * @return array
599
     */
600
    public function getUniqueVsRepetitivePieChartData($dateFrom, $dateTo, $filters = [], $canViewOthers = true)
601
    {
602
        $chart   = new PieChart();
603
        $query   = new ChartQuery($this->em->getConnection(), $dateFrom, $dateTo);
604
        $allQ    = $query->getCountQuery('asset_downloads', 'id', 'date_download', $filters);
605
        $uniqueQ = $query->getCountQuery('asset_downloads', 'lead_id', 'date_download', $filters, ['getUnique' => true]);
606
607
        if (!$canViewOthers) {
608
            $allQ->join('t', MAUTIC_TABLE_PREFIX.'assets', 'a', 'a.id = t.asset_id')
609
                ->andWhere('a.created_by = :userId')
610
                ->setParameter('userId', $this->userHelper->getUser()->getId());
611
            $uniqueQ->join('t', MAUTIC_TABLE_PREFIX.'assets', 'a', 'a.id = t.asset_id')
612
                ->andWhere('a.created_by = :userId')
613
                ->setParameter('userId', $this->userHelper->getUser()->getId());
614
        }
615
616
        $all    = $query->fetchCount($allQ);
617
        $unique = $query->fetchCount($uniqueQ);
618
619
        $repetitive = $all - $unique;
620
        $chart->setDataset($this->translator->trans('mautic.asset.unique'), $unique);
621
        $chart->setDataset($this->translator->trans('mautic.asset.repetitive'), $repetitive);
622
623
        return $chart->render();
624
    }
625
626
    /**
627
     * Get a list of popular (by downloads) assets.
628
     *
629
     * @param int    $limit
630
     * @param string $dateFrom
631
     * @param string $dateTo
632
     * @param array  $filters
633
     * @param bool   $canViewOthers
634
     *
635
     * @return array
636
     */
637
    public function getPopularAssets($limit = 10, $dateFrom = null, $dateTo = null, $filters = [], $canViewOthers = true)
638
    {
639
        $q = $this->em->getConnection()->createQueryBuilder();
640
        $q->select('COUNT(DISTINCT t.id) AS download_count, a.id, a.title')
641
            ->from(MAUTIC_TABLE_PREFIX.'asset_downloads', 't')
642
            ->join('t', MAUTIC_TABLE_PREFIX.'assets', 'a', 'a.id = t.asset_id')
643
            ->orderBy('download_count', 'DESC')
644
            ->groupBy('a.id')
645
            ->setMaxResults($limit);
646
647
        if (!$canViewOthers) {
648
            $q->andWhere('a.created_by = :userId')
649
                ->setParameter('userId', $this->userHelper->getUser()->getId());
650
        }
651
652
        $chartQuery = new ChartQuery($this->em->getConnection(), $dateFrom, $dateTo);
653
        $chartQuery->applyFilters($q, $filters);
654
        $chartQuery->applyDateFilters($q, 'date_download');
655
656
        return $q->execute()->fetchAll();
657
    }
658
659
    /**
660
     * Get a list of assets in a date range.
661
     *
662
     * @param int       $limit
663
     * @param \DateTime $dateFrom
664
     * @param \DateTime $dateTo
665
     * @param array     $filters
666
     * @param array     $options
667
     *
668
     * @return array
669
     */
670
    public function getAssetList($limit = 10, \DateTime $dateFrom = null, \DateTime $dateTo = null, $filters = [], $options = [])
671
    {
672
        $q = $this->em->getConnection()->createQueryBuilder();
673
        $q->select('t.id, t.title as name, t.date_added, t.date_modified')
674
            ->from(MAUTIC_TABLE_PREFIX.'assets', 't')
675
            ->setMaxResults($limit);
676
677
        if (!empty($options['canViewOthers'])) {
678
            $q->andWhere('t.created_by = :userId')
679
                ->setParameter('userId', $this->userHelper->getUser()->getId());
680
        }
681
682
        $chartQuery = new ChartQuery($this->em->getConnection(), $dateFrom, $dateTo);
683
        $chartQuery->applyFilters($q, $filters);
684
        $chartQuery->applyDateFilters($q, 'date_added');
685
686
        return $q->execute()->fetchAll();
687
    }
688
}
689