BackendService.php 13.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

namespace SGalinski\SgMail\Service;

/***************************************************************
 *  Copyright notice
 *
 *  (c) sgalinski Internet Services (https://www.sgalinski.de)
 *
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/

29
use SGalinski\SgMail\Domain\Model\Template;
Torsten Oppermann's avatar
Torsten Oppermann committed
30
use SGalinski\SgMail\Domain\Repository\MailRepository;
31
use SGalinski\SgMail\Domain\Repository\TemplateRepository;
32
33
34
35
36
37
38
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
39
use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository;
40
use TYPO3\CMS\Extbase\Mvc\Request;
41
use TYPO3\CMS\Extbase\Object\ObjectManager;
42
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
43
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
44
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
45
46
47
48
49
50
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;

/**
 * Backend Service class
 */
class BackendService {
Torsten Oppermann's avatar
Torsten Oppermann committed
51
52
53
54
55
56
57
	// options for the queue search filter
	const SENDER_FILTER_OPTION = 0;
	const RECIPIENT_FILTER_OPTION = 1;
	const SUBJECT_FILTER_OPTION = 2;
	const MAILTEXT_FILTER_OPTION = 3;
	const CC_FILTER_OPTION = 4;
	const BCC_FILTER_OPTION = 5;
58
59
	const FROM_NAME_FILTER_OPTION = 6;
	const REPLY_TO_NAME_FILTER_OPTION = 7;
60

61
62
63
64
65
66
	// constants for deetermining the backend mode
	const BACKEND_MODE_EDITOR = 'editor';
	const BACKEND_MODE_EDITOR_CONTROLLER = 'Mail';
	const BACKEND_MODE_QUEUE = 'queue';
	const BACKEND_MODE_QUEUE_CONTROLLER = 'Queue';

67
68
69
70
71
72
73
	/**
	 * Get all pages the be user has access to
	 *
	 * @return array
	 * @throws \InvalidArgumentException
	 */
	public static function getPages() {
74
		$out = [];
75
76
77
		/** @var $databaseConnection DatabaseConnection */
		$databaseConnection = $GLOBALS['TYPO3_DB'];
		$rows = $databaseConnection->exec_SELECTgetRows(
78
			'*',
79
			'pages',
80
			'deleted = 0 AND is_siteroot = 1'
81
82
		);

83
84
85
		foreach ($rows as $row) {
			$pageInfo = BackendUtility::readPageAccess($row['uid'], $GLOBALS['BE_USER']->getPagePermsClause(1));
			if ($pageInfo) {
86
				$rootline = BackendUtility::BEgetRootLine($pageInfo['uid'], '', TRUE);
87
88
				ksort($rootline);
				$path = '/root';
89
				foreach ($rootline as $page) {
90
91
92
					$path .= '/p' . dechex($page['uid']);
				}
				$pageInfo['path'] = $path;
93
94
95
96
				$out[] = $pageInfo;
			}
		}
		return $out;
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
	}

	/**
	 * create buttons for the backend module header
	 *
	 * @param DocHeaderComponent $docHeaderComponent
	 * @param Request $request
	 * @throws \InvalidArgumentException
	 * @throws \UnexpectedValueException
	 */
	public static function makeButtons($docHeaderComponent, $request) {
		/** @var ButtonBar $buttonBar */
		$buttonBar = $docHeaderComponent->getButtonBar();

		/** @var IconFactory $iconFactory */
		$iconFactory = GeneralUtility::makeInstance(IconFactory::class);

		// Refresh
		$refreshButton = $buttonBar->makeLinkButton()
			->setHref(GeneralUtility::getIndpEnv('REQUEST_URI'))
			->setTitle(LocalizationUtility::translate('LLL:EXT:lang/locallang_core.xlf:labels.reload', ''))
			->setIcon($iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL));
		$buttonBar->addButton($refreshButton, ButtonBar::BUTTON_POSITION_RIGHT);

		// shortcut button
		$shortcutButton = $buttonBar->makeShortcutButton()
			->setModuleName($request->getPluginName())
			->setGetVariables(
				[
					'id',
					'M'
				]
			)
			->setSetVariables([]);

		$buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
		$docHeaderComponent->getButtonBar();
	}
Torsten Oppermann's avatar
Torsten Oppermann committed
135
136
137
138

	/**
	 * Retrieves the next site root in the page hierarchy from the current page
	 *
Torsten Oppermann's avatar
Torsten Oppermann committed
139
	 * @param int $currentPid
140
	 * @return int
Torsten Oppermann's avatar
Torsten Oppermann committed
141
	 */
Torsten Oppermann's avatar
Torsten Oppermann committed
142
143
144
	public static function getSiteRoot($currentPid) {
		$rootLine = BackendUtility::BEgetRootLine((int) $currentPid);
		$siteRoot = ['uid' => 0];
145

Torsten Oppermann's avatar
Torsten Oppermann committed
146
		foreach ($rootLine as $page) {
147
			if ((int) $page['is_siteroot'] === 1) {
Torsten Oppermann's avatar
Torsten Oppermann committed
148
149
150
151
152
				$siteRoot = $page;
				break;
			}
		}

153
		return $siteRoot['uid'];
Torsten Oppermann's avatar
Torsten Oppermann committed
154
	}
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
	/**
	 * Get the selected templates for the selected language
	 *
	 * @param string $selectedExtension
	 * @param string $selectedTemplate
	 * @param array $languages
	 * @param int $pid
	 * @return array
	 * @throws \InvalidArgumentException
	 */
	public static function getSelectedTemplates(
		$selectedExtension, $selectedTemplate, array $languages, $pid
	) {
		$selectedTemplates = [];

		$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		/** @var TemplateRepository $templateRepository */
		$templateRepository = $objectManager->get(TemplateRepository::class);

		foreach ($languages as $language) {
			$selectedTemplates[$language['isocode']] = $templateRepository->findOneByTemplate(
				$selectedExtension, $selectedTemplate, $language['isocode'], $pid
			);
		}

		return $selectedTemplates;
	}

184
185
186
187
188
189
190
	/**
	 * get an array of all the locales for the activated languages
	 *
	 * @return array
	 * @throws \InvalidArgumentException
	 */
	public static function getLanguages() {
191
192
193
194
195
196
197
198
		/** @var $databaseConnection DatabaseConnection */
		$databaseConnection = $GLOBALS['TYPO3_DB'];
		/** @var QueryResultInterface $rows */
		$rows = $databaseConnection->exec_SELECTgetRows(
			'*',
			'sys_language',
			'hidden = 0'
		);
199

200
201
		$languages = [];

202
		// adding default language
203
		$languages[] = ['isocode' => MailTemplateService::DEFAULT_LANGUAGE, 'name' => LocalizationUtility::translate(
204
			'backend.language_default', 'SgMail'
205
		)];
206

207
208
209
		foreach ($rows as $language) {
			$languages[] = ['isocode' => $language['language_isocode'],
				'name' => $language['title']];
210
211
212
213
		}

		return $languages;
	}
214

215
216
217
	/**
	 * get an array of all the labels for the activated languages
	 *
218
	 * @param array $languages
219
220
221
	 * @return array
	 * @throws \InvalidArgumentException
	 */
222
223
	public static function getLanguageLabels(array $languages) {
		$languageLabels = [];
224

225
226
		foreach ($languages as $language) {
			$languageLabels[$language['isocode']] = $language['name'];
227
228
		}

229
		return $languageLabels;
230
231
	}

232
233
234
235
236
237
238
239
	/**
	 * Get the languages in an array suitable for filtering
	 *
	 * @return array
	 * @throws \InvalidArgumentException
	 */
	public static function getLanguagesForFilter() {
		$languages = self::getLanguages();
240
		array_unshift($languages, ['isocode' => '', 'name' => '']);
241

242
		$filterLanguages = [];
243
244
245
		if (count($languages) > 0) {
			foreach ($languages as $language) {
				$filterLanguages[$language['isocode']] = $language['name'];
246
			}
247
248
249
250
251
252
		}

		return $filterLanguages;
	}

	/**
253
	 * Get the template keys in an array suitable for filtering
254
255
256
257
258
259
260
261
	 *
	 * @return array
	 */
	public static function getTemplatesForFilter() {
		$registerArray = MailTemplateService::getRegisterArray();
		$templates = [];
		foreach ($registerArray as $extensions) {
			foreach ($extensions as $template => $key) {
262
				$templates[$key['extension']][] = $key['templateName'];
263
264
265
266
267
268
			}
		}
		array_unshift($templates, '');

		return $templates;
	}
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

	/**
	 * Save or update the template in the DB, depending if it already exists or not
	 *
	 * @param int $pid
	 * @param string $selectedExtension
	 * @param string $selectedTemplate
	 * @param string $language
	 * @param array $templateData
	 * @return Template $template
	 * @throws \InvalidArgumentException
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
	 */
	public static function saveTemplate($pid, $selectedExtension, $selectedTemplate, $language, $templateData) {
		$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		/** @var TemplateRepository $templateRepository */
		$templateRepository = $objectManager->get(TemplateRepository::class);

		/** @var Template $template */
		$template = $templateRepository->findOneByTemplate(
			$selectedExtension, $selectedTemplate, $language, $pid
		);

		$templateAlreadyExists = TRUE;
		$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		if ($template === NULL) {
			$templateAlreadyExists = FALSE;
			$template = $objectManager->get(Template::class);
		}

		$template->setExtensionKey($selectedExtension);
		$template->setTemplateName($selectedTemplate);
		$template->setLanguage($language);
		$template->setContent($templateData['content']);
		$template->setSubject($templateData['subject']);
		$template->setFromName($templateData['fromName']);
		$template->setFromMail($templateData['fromMail']);
		$template->setCc($templateData['cc']);
		$template->setBcc($templateData['bcc']);
		$template->setReplyTo($templateData['replyTo']);
310
		$template->setToAddress($templateData['toAddress']);
311
312
313
314
315
316
317

		if ($templateAlreadyExists) {
			$templateRepository->update($template);
		} else {
			$templateRepository->add($template);
		}

318
319
320
321
		$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		$persistenceManager = $objectManager->get(PersistenceManager::class);
		$persistenceManager->persistAll();

322
323
		return $template;
	}
324

Torsten Oppermann's avatar
Torsten Oppermann committed
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
	/**
	 * Generate a csv string from the queues, respecting the given filters
	 *
	 * @param array $filters
	 * @return string
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
	 * @throws \InvalidArgumentException
	 */
	public static function getCsvFromQueue(array $filters = []) {
		$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		/** @var MailRepository $mailRepository */
		$mailRepository = $objectManager->get(MailRepository::class);

		$pageUid = (int) GeneralUtility::_GP('id');
		/** @var array $queue */
		$queue = $mailRepository->findAllEntries($pageUid, 0, $filters);
		$totalQueueSize = count($queue);
		$exportString = '';

		if ($totalQueueSize && $queue) {
			$ignoreFields = ['uid', 'pid', 'tstamp',
				'password', 'starttime', 'endtime', 'deleted', 'sent', 'priority', 'crdate', 'cruser_id', 'hidden'];
			$dateFields = ['tstamp', 'starttime', 'endtime', 'crdate'];

			$export = [[]];
			$first = TRUE;

			/** @var array $mail */
			foreach ($queue as $mail) {
				if ($first) {
					$first = FALSE;
					foreach ($mail as $field => $value) {
						if (!in_array($field, $ignoreFields, TRUE)) {
							$label = isset($GLOBALS['TCA']['tx_sgmail_domain_model_mail']['columns'][$field]) ?
								$GLOBALS['TCA']['fe_users']['columns'][$field]['label'] : '';
							if (strpos($label, 'LLL:') === 0) {
								$label = $GLOBALS['LANG']->sL($label);
							}
							$export[0][] = $label ?: $field;
						}
					}
				}
			}

			$line = 1;
			/** @var array $mail */
			foreach ($queue as $mail) {
				foreach ($mail as $field => $value) {
					if (!in_array($field, $ignoreFields, TRUE)) {
						if (in_array($field, $dateFields, TRUE)) {
							$export[$line][] = $value ? date('d.m.Y', $value) : '';
						} else {
							$export[$line][] = (string) $value;
						}
					}
				}
				$line++;
			}

			foreach ($export as $line) {
				/** @var array $line */
				$fields = [];
				foreach ($line as $field) {
					$fields[] = '"' . $field . '"';
				}
				$exportString .= implode(',', $fields) . ';' . LF;
			}
		}

		return trim(preg_replace('/\s\s+/', ' ', strip_tags($exportString)));
	}
396
397
398
399
400
401
402
403

	/**
	 * Filter the register array to have only whitelisted templates for this domain
	 *
	 * @param int $siteRootId
	 * @throws \InvalidArgumentException
	 * @throws \BadFunctionCallException
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
404
	 * @return array
405
	 */
406
	public static function getWhitelistedTemplates($siteRootId): array {
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
		$siteRootId = (int) $siteRootId;
		$registerArray = MailTemplateService::getRegisterArray();
		$extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_mail'], []);

		if (isset($extensionConfiguration['excludeTemplates']) && $extensionConfiguration['excludeTemplates'] !== '') {
			$excludedTemplatesWithSiteId = GeneralUtility::trimExplode(
				';', $extensionConfiguration['excludeTemplates'], TRUE
			);

			foreach ($excludedTemplatesWithSiteId as $currentSite) {
				$currentSiteBlacklist = GeneralUtility::trimExplode(',', $currentSite, TRUE);
				if ((int) $currentSiteBlacklist[0] === $siteRootId) {
					foreach ($currentSiteBlacklist as $excludedTemplate) {
						list($extensionKey, $templateName) = GeneralUtility::trimExplode('.', $excludedTemplate);
						if ($extensionKey && $templateName && isset($registerArray[$extensionKey][$templateName])) {
							unset($registerArray[$extensionKey][$templateName]);
						}
					}
				}
			}
		}

429
430
431
432
433
434
435
436
437
438
439
440
441
		// filter out  excluded templates from all domains
		if (isset($extensionConfiguration['excludeTemplatesFromAllDomains']) && $extensionConfiguration['excludeTemplatesFromAllDomains'] !== '') {
			$excludedTemplates = GeneralUtility::trimExplode(
				',', $extensionConfiguration['excludeTemplates'], TRUE
			);
			foreach ($excludedTemplates as $excludedTemplate) {
				list($extensionKey, $templateName) = GeneralUtility::trimExplode('.', $excludedTemplate);
				if ($extensionKey && $templateName && isset($registerArray[$extensionKey][$templateName])) {
					unset($registerArray[$extensionKey][$templateName]);
				}
			}
		}

442
443
		return $registerArray;
	}
444
}