Completed
Push — 7LTS_compatible ( b51d35...40d99a )
by Tomas Norre
32:08
created

BeServices::getElement()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 7
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 5
nc 1
nop 3
1
<?php
2
3
namespace AOE\Languagevisibility\Services;
4
5
/***************************************************************
6
 * Copyright notice
7
 *
8
 * (c) 2007 AOE media ([email protected])
9
 * All rights reserved
10
 *
11
 * This script is part of the TYPO3 project. The TYPO3 project is
12
 * free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * The GNU General Public License can be found at
18
 * http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 * This script is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
class BeServices extends AbstractServices {
29
30
	protected static $cache_canBeUserCopyDelete = array();
31
32
	protected static $visibleFlagsCache = array();
33
34
	protected static $cache_isVisible = array();
35
36
	/**
37
	 *
38
	 * @param $uid
39
	 * @param $table
40
	 * @return string
41
	 */
42
	public static function getVisibleFlagsForElement($uid, $table) {
43
		$cacheKey = $uid . ':' . $table;
44
45
		$cacheManager = tx_languagevisibility_cacheManager::getInstance();
46
		$isCacheEnabled = $cacheManager->isCacheEnabled();
47
		$cacheData = $cacheManager->get('visibleFlagsCache');
48
49
		if (! $isCacheEnabled || ! isset($cacheData[$cacheKey])) {
50
51
			$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
52
			$elementfactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_elementFactory', $dao);
53
			try {
54
				$element = $elementfactory->getElementForTable($table, $uid);
55
			} catch ( Exception $e ) {
0 ignored issues
show
Bug introduced by
The class AOE\Languagevisibility\Services\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
56
				return '-';
57
			}
58
59
			$languageRep = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_languagerepository');
60
			$languageList = $languageRep->getLanguages();
61
62
			$visibility = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_visibilityService');
63
64
			$visibleFlags = array();
65
			foreach ( $languageList as $language ) {
66
				if ($visibility->isVisible($language, $element)) {
67
					$visibleFlags[] = $language->getFlagImg(0);
68
				}
69
			}
70
71
			$cacheData[$cacheKey] = implode('', $visibleFlags);
72
			$cacheManager->set('visibleFlagsCache', $cacheData);
73
		}
74
75
		return $cacheData[$cacheKey];
76
	}
77
78
	/**
79
	 * Helper function to get an element by uid and tablename.
80
	 *
81
	 * @param int $uid
82
	 * @param string $table
83
	 * @param boolean $overlay_ids
84
	 * @return tx_languagevisibility_element
85
	 */
86
	public static function getElement($uid, $table, $overlay_ids = TRUE) {
87
		$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
88
		$elementfactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_elementFactory', $dao);
89
		$element = $elementfactory->getElementForTable($table, $uid, $overlay_ids);
90
91
		return $element;
92
	}
93
94
	/**
95
	 * Helper function to check i an element with a given uid and tablename is visible for a languageid.
96
	 *
97
	 * @param int $uid
98
	 * @param string $table
99
	 * @param int $languageUid
100
	 * @param bool $omitLocal
101
	 * @return boolean
102
	 */
103
	public static function isVisible($uid, $table, $languageUid, $omitLocal = FALSE) {
104
105
		$cacheKey = sprintf('%s:%d:%d:%d', $table, $uid, $languageUid, $omitLocal);
106
107
		if (!isset(self::$cache_isVisible[$cacheKey])) {
108
109
			$rep = tx_languagevisibility_languagerepository::makeInstance();
110
			$language = $rep->getLanguageById($languageUid);
111
112
			$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
113
			$elementfactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_elementFactory', $dao);
114
115
			try {
116
				$element = $elementfactory->getElementForTable($table, $uid);
117
			} catch ( Exception $e ) {
0 ignored issues
show
Bug introduced by
The class AOE\Languagevisibility\Services\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
118
				return FALSE;
119
			}
120
121
			$visibility = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_visibilityService');
122
123
			self::$cache_isVisible[$cacheKey] = $visibility->isVisible($language, $element, $omitLocal);
124
		}
125
126
		return self::$cache_isVisible[$cacheKey];
127
	}
128
129
	/**
130
	 * Helper function to check if the current backend user has rights to cut,copy or delete
131
	 *
132
	 * @return boolean
133
	 */
134
	public static function canCurrrentUserCutCopyMoveDelete() {
135
			//current element is no overlay -> if user has rights to cutMoveDelete or is an admin don't filter commants
136
		/** @var $beUser tx_languagevisibility_beUser */
137
		$beUser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_beUser');
138
		$userId = $beUser->getUid();
139
140
		if (!isset(self::$cache_canBeUserCopyDelete[$userId])) {
141
			if ($beUser->allowCutCopyMoveDelete() || $beUser->isAdmin()) {
142
				$result = TRUE;
143
			} else {
144
				$result = FALSE;
145
			}
146
147
			self::$cache_canBeUserCopyDelete[$userId] = $result;
148
		}
149
150
		return self::$cache_canBeUserCopyDelete[$userId];
151
	}
152
153
	/**
154
	 * Helper function to check if a record from a given table in an overlayrecord
155
	 *
156
	 * @param array $row
157
	 * @param string $table
158
	 * @return boolean
159
	 */
160
	public static function isOverlayRecord($row, $table) {
161
162
		$result = FALSE;
163
164
		switch ($table) {
165
			case 'pages_language_overlay' :
166
				$result = TRUE;
167
				break;
168
			case 'pages' :
169
				$result = FALSE;
170
				break;
171
			default:
172
173
				if (in_array($table, tx_languagevisibility_visibilityService::getSupportedTables())) {
174
					$tanslationIdField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
175
					if ($tanslationIdField != '') {
176
							// if the field which points to the orginal of the translation is
177
							// not 0 a translation exists and we have an overlay record
178
						$result = $row[$tanslationIdField] != 0;
179
					}
180
				}
181
182
				break;
183
		}
184
185
		return $result;
186
	}
187
188
	/**
189
	 * Static service method to determine if an record has a translation in any language
190
	 *
191
	 * @param int $uid
192
	 * @param string $table
193
	 * @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
194
	 */
195
	public static function hasTranslationInAnyLanguage($uid, $table) {
196
		$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
197
		$elementfactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_elementFactory', $dao);
198
199
		try {
200
			$element = $elementfactory->getElementForTable($table, $uid);
201
			$rep = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_languagerepository');
202
			$languages = $rep->getLanguages();
203
204
			foreach ( $languages as $language ) {
205
					//skip default language
206
				if ($language->getUid() != 0) {
207
					if ($element->hasTranslation($language->getUid())) {
208
						return TRUE;
209
					}
210
				}
211
			}
212
		} catch ( UnexpectedValueException $e ) {
0 ignored issues
show
Bug introduced by
The class AOE\Languagevisibility\S...nexpectedValueException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
213
				//the element can not be handeld by language visibility
214
			return FALSE;
215
		}
216
		return FALSE;
217
	}
218
219
	/**
220
	 * Check if given element has traslation in given language
221
	 *
222
	 * @param int $elementUid
223
	 * @param string $table
224
	 * @param int $languageUid
225
	 * @return boolean
226
	 */
227
	public static function hasTranslation($elementUid, $table, $languageUid) {
228
		$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
229
		$elementfactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_elementFactory', $dao);
230
231
		$result = FALSE;
232
		try {
233
			$element = $elementfactory->getElementForTable($table, $elementUid);
234
			$result = $element->hasTranslation($languageUid);
235
236
		} catch ( UnexpectedValueException $e ) {
0 ignored issues
show
Bug introduced by
The class AOE\Languagevisibility\S...nexpectedValueException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
237
				//the element can not be handeld by language visibility
238
			$result = FALSE;
239
		}
240
241
		return $result;
242
	}
243
244
	/**
245
	 * checks if the current BE_USER has access to the page record:
246
	 * that is the case if:
247
	 * a) new page created -> always because then the languagevisibility is set to never for all languages where the user has no access
248
	 * b) edit page record: only if the record is only visible in languages where the user has access to
249
	 * b.1) also if the languages taht are visibile and falls back to allowed languages
250
	 * c) delete: same as for edit (only if user has access to all visible languages)
251
	 */
252
	public static function hasUserAccessToPageRecord($id, $cmd = 'edit') {
253
		if ($cmd == 'new') {
254
			return TRUE;
255
		}
256
		if (!is_numeric($id)) {
257
			return FALSE;
258
		}
259
		$rep = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_languagerepository');
260
		$languages = $rep->getLanguages();
261
		foreach ( $languages as $language ) {
262
			if (self::isVisible($id, 'pages', $language->getUid())) {
263
				if (!$GLOBALS['BE_USER']->checkLanguageAccess($language->getUid())) {
264
						//no access to a visible language: check fallbacks
265
					$isInFallback = FALSE;
266
					$fallbacks = $language->getFallbackOrder(self::getContextElement('pages', $id));
267
					foreach ($fallbacks as $lId) {
268
						if ($GLOBALS['BE_USER']->checkLanguageAccess($lId)) {
269
							$isInFallback = TRUE;
270
							continue;
271
						}
272
					}
273
					if (!$isInFallback) {
274
						return FALSE;
275
					}
276
				}
277
			}
278
		}
279
		return TRUE;
280
	}
281
282
	/**
283
	 * checks if the current BE_USER has access to a record:
284
	 * that is the case if:
285
	 * a) new page created -> always because then the languagevisibility is set to never for all languages where the user has no access
286
	 * b) edit page record: only if the record is only visible in languages where the user has access to
287
	 */
288
	public static function hasUserAccessToEditRecord($table, $id) {
289
		if (!is_numeric($id)) {
290
			return FALSE;
291
		}
292
		if (!self::isSupportedTable($table)) {
293
			return TRUE;
294
		}
295
296
			// check if overlay record:
297
		$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
298
		$row = $dao->getRecord($id, $table);
299
300
			// @TODO check TCA for languagefield
301
		if (self::isOverlayRecord($row, $table)) {
302
303
			if ($GLOBALS['BE_USER']->checkLanguageAccess($row['sys_language_uid'])) {
304
				return TRUE;
305
			} else {
306
				return FALSE;
307
			}
308
		}
309
310
		$rep = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_languagerepository');
311
		$languages = $rep->getLanguages();
312
		foreach ($languages as $language) {
313
			if (self::isVisible($id, $table, $language->getUid())) {
314
				if (!$GLOBALS['BE_USER']->checkLanguageAccess($language->getUid())) {
315
						// no access to a visible language: check fallbacks
316
					$isInFallback = FALSE;
317
					$fallbacks = $language->getFallbackOrder(self::getContextElement($table, $id));
318
					foreach ($fallbacks as $lId) {
319
						if ($GLOBALS['BE_USER']->checkLanguageAccess($lId)) {
320
								// TODO - write testcase - this can't be right
321
							$isInFallback = TRUE;
322
							continue;
323
						}
324
					}
325
					if (!$isInFallback) {
326
						return FALSE;
327
					}
328
				}
329
			}
330
		}
331
		return TRUE;
332
	}
333
334
	/**
335
	 * @param string $table
336
	 * @param int $id
337
	 * @return string
338
	 */
339
	protected function getContextElement($table, $id) {
340
		$dao = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_daocommon');
341
		$elementfactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_elementFactory', $dao);
342
		try {
343
			$element = $elementfactory->getElementForTable($table, $id);
344
		} catch ( Exception $e ) {
0 ignored issues
show
Bug introduced by
The class AOE\Languagevisibility\Services\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
345
			return '-';
346
		}
347
		return $element;
348
	}
349
350
351
	/**
352
	 * Method to check if the inheritance is enabled or not
353
	 *
354
	 * @return boolean
355
	 */
356
	protected function isInheritanceEnabled() {
357
		$confArr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['languagevisibility']);
358
		if (is_array($confArr)) {
359
			return ($confArr['inheritanceEnabled'] == 1);
360
		} else {
361
			return FALSE;
362
		}
363
	}
364
365
	/**
366
	 * Method to check if the inheritance is enabled or not
367
	 *
368
	 * @return boolean
369
	 */
370
	protected function isTranslatedAsDefaultEnabled() {
371
		$confArr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['languagevisibility']);
372
		if (is_array($confArr)) {
373
			return ($confArr['translatedAsDefaultEnabled'] == 1);
374
		} else {
375
			return FALSE;
376
		}
377
	}
378
379
	/**
380
	 * returns array with the visibility options that are allowed for the current user.
381
	 *
382
	 * @param tx_languagevisibility_language $language
383
	 * @param bool $isOverlay
384
	 * @param null $element
385
	 * @return array
386
	 */
387
	public static function getAvailableOptionsForLanguage(tx_languagevisibility_language $language, $isOverlay = FALSE, $element = NULL) {
388
389
		$element = $element === NULL ? self::getContextElement('pages', self::_guessCurrentPid()) : $element;
390
391
		$elementSupportsInheritance = $element->supportsInheritance();
0 ignored issues
show
Bug introduced by
The method supportsInheritance cannot be called on $element (of type string|null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
392
393
		$uid = $language->getUid();
394
		$select = array();
395
		$useInheritance = ($elementSupportsInheritance && self::isInheritanceEnabled());
396
397
		if (! $isOverlay) {
398
			if ($uid == 0) {
399
				$select['-'] = '-';
400
				$select['yes'] = 'yes';
401
				$select['no'] = 'no';
402
				if ($useInheritance) {
403
					$select['no+'] = 'no+';
404
				}
405
			} else {
406
				$select['-'] = '-';
407
				$select['yes'] = 'yes';
408
				$select['no'] = 'no';
409
				if ($useInheritance) {
410
					$select['no+'] = 'no+';
411
				}
412
				$select['t'] = 't';
413
				$select['f'] = 'f';
414
			}
415
416
				//check permissions, if user has no permission only no for the language is allowed
417
				// if the user has permissions for languages that act as fallbacklanguage: then the languages that falls back can have "-" in the options!
418
			if (! $GLOBALS['BE_USER']->checkLanguageAccess($uid)) {
419
420
					//check if the language falls back to one of the languages the user has permissions:
421
				$isInFallback = FALSE;
422
				$fallbacks = $language->getFallbackOrder($element);
423
				foreach ( $fallbacks as $lId ) {
424
					if ($GLOBALS['BE_USER']->checkLanguageAccess($lId)) {
425
						$isInFallback = TRUE;
426
						continue;
427
					}
428
				}
429
				$select = array();
430
				if ($isInFallback) {
431
					$select['-'] = '-';
432
				}
433
434
				if ($uid != 0 && self::isTranslatedAsDefaultEnabled()) {
435
					$select['t'] = 't';
436
				}
437
				$select['no'] = 'no';
438
				if ($useInheritance) {
439
					$select['no+'] = 'no+';
440
				}
441
			}
442
		} else {
443
				//overlays elements can only have "force to no" or "force to no inherited"
444
			$select['-'] = '-';
445
			$select['no'] = 'no';
446
			if ($useInheritance) {
447
				$select['no+'] = 'no+';
448
			}
449
		}
450
451
		/**
452
		 * Get translations of labels from the locallang file
453
		 */
454
		if (is_object($GLOBALS['LANG'])) {
455
				//get value from locallang:
456
			foreach ( $select as $k => $v ) {
457
				$select[$k] = $GLOBALS['LANG']->sl('LLL:EXT:languagevisibility/locallang_db.xml:tx_languagevisibility_visibility.I.' . $v);
458
			}
459
		}
460
461
		return $select;
462
	}
463
464
	/**
465
	 * @return mixed
466
	 */
467
	protected static function _guessCurrentPid() {
468
		return \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id');
469
	}
470
471
	/**
472
	 * This method is used to create an visibility array with the default settings
473
	 * for all languages.
474
	 *
475
	 * @return array
476
	 */
477
	public static function getDefaultVisibilityArray() {
478
		/* @var $languageRep tx_languagevisibility_languagerepository */
479
		$languageRep = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_languagevisibility_languagerepository');
480
		$languageList = $languageRep->getLanguages();
481
		$default = array();
482
		foreach ( $languageList as $language ) {
483
			$options = self::getAvailableOptionsForLanguage($language);
484
			$default[$language->getUid()] = array_shift(array_keys($options));
0 ignored issues
show
Bug introduced by
array_keys($options) cannot be passed to array_shift() as the parameter $array expects a reference.
Loading history...
485
486
		}
487
		return $default;
488
	}
489
490
	/**
491
	 * This method is used to get the table where original elements of the
492
	 * given table are stored.
493
	 *
494
	 * @param string $table
495
	 * @return string
496
	 */
497
	public static function getOriginalTableOfTranslation($table) {
498
		$translationTable = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
499
		if ($translationTable != '') {
500
			return $translationTable;
501
		} else {
502
			return $table;
503
		}
504
	}
505
506
	/**
507
	 * This method is used to determine the original uid of a translation
508
	 *
509
	 * @param array $row
510
	 * @param string $table
511
	 * @return string
512
	 */
513
	public static function getOriginalUidOfTranslation($row, $table) {
514
		if (is_array($row) && is_array($GLOBALS['TCA'])) {
515
			return $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']];
516
		} else {
517
			return 0;
518
		}
519
	}
520
}
521