[TASK] Replace deprecated API calls and label references
[TYPO3CMS/Extensions/languagevisibility.git] / class.tx_languagevisibility_beservices.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007 AOE media (dev@aoemedia.de)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 class tx_languagevisibility_beservices extends tx_languagevisibility_abstractservices {
26
27 protected static $cache_canBeUserCopyDelete = array();
28
29 protected static $visibleFlagsCache = array();
30
31 protected static $cache_isVisible = array();
32
33 /**
34 *
35 * @param $uid
36 * @param $table
37 * @return string
38 */
39 public static function getVisibleFlagsForElement($uid, $table) {
40 $cacheKey = $uid . ':' . $table;
41
42 $cacheManager = tx_languagevisibility_cacheManager::getInstance();
43 $isCacheEnabled = $cacheManager->isCacheEnabled();
44 $cacheData = $cacheManager->get('visibleFlagsCache');
45
46 if (! $isCacheEnabled || ! isset($cacheData[$cacheKey])) {
47
48 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
49 $elementfactory = t3lib_div::makeInstance('tx_languagevisibility_elementFactory', $dao);
50 try {
51 $element = $elementfactory->getElementForTable($table, $uid);
52 } catch ( Exception $e ) {
53 return '-';
54 }
55
56 $languageRep = t3lib_div::makeInstance('tx_languagevisibility_languagerepository');
57 $languageList = $languageRep->getLanguages();
58
59 $visibility = t3lib_div::makeInstance('tx_languagevisibility_visibilityService');
60
61 $visibleFlags = array();
62 foreach ( $languageList as $language ) {
63 if ($visibility->isVisible($language, $element)) {
64 $visibleFlags[] = $language->getFlagImg(0);
65 }
66 }
67
68 $cacheData[$cacheKey] = implode('', $visibleFlags);
69 $cacheManager->set('visibleFlagsCache', $cacheData);
70 }
71
72 return $cacheData[$cacheKey];
73 }
74
75 /**
76 * Helper function to get an element by uid and tablename.
77 *
78 * @param int $uid
79 * @param string $table
80 * @param boolean $overlay_ids
81 * @return tx_languagevisibility_element
82 */
83 public static function getElement($uid, $table, $overlay_ids = TRUE) {
84 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
85 $elementfactory = t3lib_div::makeInstance('tx_languagevisibility_elementFactory', $dao);
86 $element = $elementfactory->getElementForTable($table, $uid, $overlay_ids);
87
88 return $element;
89 }
90
91 /**
92 * Helper function to check i an element with a given uid and tablename is visible for a languageid.
93 *
94 * @param int $uid
95 * @param string $table
96 * @param int $languageUid
97 * @param bool $omitLocal
98 * @return boolean
99 */
100 public static function isVisible($uid, $table, $languageUid, $omitLocal = FALSE) {
101
102 $cacheKey = sprintf('%s:%d:%d:%d', $table, $uid, $languageUid, $omitLocal);
103
104 if (!isset(self::$cache_isVisible[$cacheKey])) {
105
106 $rep = tx_languagevisibility_languagerepository::makeInstance();
107 $language = $rep->getLanguageById($languageUid);
108
109 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
110 $elementfactory = t3lib_div::makeInstance('tx_languagevisibility_elementFactory', $dao);
111
112 try {
113 $element = $elementfactory->getElementForTable($table, $uid);
114 } catch ( Exception $e ) {
115 return FALSE;
116 }
117
118 $visibility = t3lib_div::makeInstance('tx_languagevisibility_visibilityService');
119
120 self::$cache_isVisible[$cacheKey] = $visibility->isVisible($language, $element, $omitLocal);
121 }
122
123 return self::$cache_isVisible[$cacheKey];
124 }
125
126 /**
127 * Helper function to check if the current backend user has rights to cut,copy or delete
128 *
129 * @return boolean
130 */
131 public static function canCurrrentUserCutCopyMoveDelete() {
132 //current element is no overlay -> if user has rights to cutMoveDelete or is an admin don't filter commants
133 /** @var $beUser tx_languagevisibility_beUser */
134 $beUser = t3lib_div::makeInstance('tx_languagevisibility_beUser');
135 $userId = $beUser->getUid();
136
137 if (!isset(self::$cache_canBeUserCopyDelete[$userId])) {
138 if ($beUser->allowCutCopyMoveDelete() || $beUser->isAdmin()) {
139 $result = TRUE;
140 } else {
141 $result = FALSE;
142 }
143
144 self::$cache_canBeUserCopyDelete[$userId] = $result;
145 }
146
147 return self::$cache_canBeUserCopyDelete[$userId];
148 }
149
150 /**
151 * Helper function to check if a record from a given table in an overlayrecord
152 *
153 * @param array $row
154 * @param string $table
155 * @return boolean
156 */
157 public static function isOverlayRecord($row, $table) {
158
159 $result = FALSE;
160
161 switch ($table) {
162 case 'pages_language_overlay' :
163 $result = TRUE;
164 break;
165 case 'pages' :
166 $result = FALSE;
167 break;
168 default:
169
170 if (in_array($table, tx_languagevisibility_visibilityService::getSupportedTables())) {
171 $tanslationIdField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
172 if ($tanslationIdField != '') {
173 // if the field which points to the orginal of the translation is
174 // not 0 a translation exists and we have an overlay record
175 $result = $row[$tanslationIdField] != 0;
176 }
177 }
178
179 break;
180 }
181
182 return $result;
183 }
184
185 /**
186 * Static service method to determine if an record has a translation in any language
187 *
188 * @param int $uid
189 * @param string $table
190 * @return boolean.
191 */
192 public static function hasTranslationInAnyLanguage($uid, $table) {
193 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
194 $elementfactory = t3lib_div::makeInstance('tx_languagevisibility_elementFactory', $dao);
195
196 try {
197 $element = $elementfactory->getElementForTable($table, $uid);
198 $rep = t3lib_div::makeInstance('tx_languagevisibility_languagerepository');
199 $languages = $rep->getLanguages();
200
201 foreach ( $languages as $language ) {
202 //skip default language
203 if ($language->getUid() != 0) {
204 if ($element->hasTranslation($language->getUid())) {
205 return TRUE;
206 }
207 }
208 }
209 } catch ( UnexpectedValueException $e ) {
210 //the element can not be handeld by language visibility
211 return FALSE;
212 }
213 return FALSE;
214 }
215
216 /**
217 * Check if given element has traslation in given language
218 *
219 * @param int $elementUid
220 * @param string $table
221 * @param int $languageUid
222 * @return boolean
223 */
224 public static function hasTranslation($elementUid, $table, $languageUid) {
225 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
226 $elementfactory = t3lib_div::makeInstance('tx_languagevisibility_elementFactory', $dao);
227
228 $result = FALSE;
229 try {
230 $element = $elementfactory->getElementForTable($table, $elementUid);
231 $result = $element->hasTranslation($languageUid);
232
233 } catch ( UnexpectedValueException $e ) {
234 //the element can not be handeld by language visibility
235 $result = FALSE;
236 }
237
238 return $result;
239 }
240
241 /**
242 * checks if the current BE_USER has access to the page record:
243 * that is the case if:
244 * a) new page created -> always because then the languagevisibility is set to never for all languages where the user has no access
245 * b) edit page record: only if the record is only visible in languages where the user has access to
246 * b.1) also if the languages taht are visibile and falls back to allowed languages
247 * c) delete: same as for edit (only if user has access to all visible languages)
248 */
249 public static function hasUserAccessToPageRecord($id, $cmd = 'edit') {
250 if ($cmd == 'new') {
251 return TRUE;
252 }
253 if (!is_numeric($id)) {
254 return FALSE;
255 }
256 $rep = t3lib_div::makeInstance('tx_languagevisibility_languagerepository');
257 $languages = $rep->getLanguages();
258 foreach ( $languages as $language ) {
259 if (self::isVisible($id, 'pages', $language->getUid())) {
260 if (!$GLOBALS['BE_USER']->checkLanguageAccess($language->getUid())) {
261 //no access to a visible language: check fallbacks
262 $isInFallback = FALSE;
263 $fallbacks = $language->getFallbackOrder(self::getContextElement('pages', $id));
264 foreach ($fallbacks as $lId) {
265 if ($GLOBALS['BE_USER']->checkLanguageAccess($lId)) {
266 $isInFallback = TRUE;
267 continue;
268 }
269 }
270 if (!$isInFallback) {
271 return FALSE;
272 }
273 }
274 }
275 }
276 return TRUE;
277 }
278
279 /**
280 * checks if the current BE_USER has access to a record:
281 * that is the case if:
282 * a) new page created -> always because then the languagevisibility is set to never for all languages where the user has no access
283 * b) edit page record: only if the record is only visible in languages where the user has access to
284 */
285 public static function hasUserAccessToEditRecord($table, $id) {
286 if (!is_numeric($id)) {
287 return FALSE;
288 }
289 if (!self::isSupportedTable($table)) {
290 return TRUE;
291 }
292
293 // check if overlay record:
294 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
295 $row = $dao->getRecord($id, $table);
296
297 // @TODO check TCA for languagefield
298 if (self::isOverlayRecord($row, $table)) {
299
300 if ($GLOBALS['BE_USER']->checkLanguageAccess($row['sys_language_uid'])) {
301 return TRUE;
302 } else {
303 return FALSE;
304 }
305 }
306
307 $rep = t3lib_div::makeInstance('tx_languagevisibility_languagerepository');
308 $languages = $rep->getLanguages();
309 foreach ($languages as $language) {
310 if (self::isVisible($id, $table, $language->getUid())) {
311 if (!$GLOBALS['BE_USER']->checkLanguageAccess($language->getUid())) {
312 // no access to a visible language: check fallbacks
313 $isInFallback = FALSE;
314 $fallbacks = $language->getFallbackOrder(self::getContextElement($table, $id));
315 foreach ($fallbacks as $lId) {
316 if ($GLOBALS['BE_USER']->checkLanguageAccess($lId)) {
317 // TODO - write testcase - this can't be right
318 $isInFallback = TRUE;
319 continue;
320 }
321 }
322 if (!$isInFallback) {
323 return FALSE;
324 }
325 }
326 }
327 }
328 return TRUE;
329 }
330
331 /**
332 * @param string $table
333 * @param int $id
334 * @return string
335 */
336 protected function getContextElement($table, $id) {
337 $dao = t3lib_div::makeInstance('tx_languagevisibility_daocommon');
338 $elementfactory = t3lib_div::makeInstance('tx_languagevisibility_elementFactory', $dao);
339 try {
340 $element = $elementfactory->getElementForTable($table, $id);
341 } catch ( Exception $e ) {
342 return '-';
343 }
344 return $element;
345 }
346
347
348 /**
349 * Method to check if the inheritance is enabled or not
350 *
351 * @return boolean
352 */
353 protected function isInheritanceEnabled() {
354 $confArr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['languagevisibility']);
355 if (is_array($confArr)) {
356 return ($confArr['inheritanceEnabled'] == 1);
357 } else {
358 return FALSE;
359 }
360 }
361
362 /**
363 * Method to check if the inheritance is enabled or not
364 *
365 * @return boolean
366 */
367 protected function isTranslatedAsDefaultEnabled() {
368 $confArr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['languagevisibility']);
369 if (is_array($confArr)) {
370 return ($confArr['translatedAsDefaultEnabled'] == 1);
371 } else {
372 return FALSE;
373 }
374 }
375
376 /**
377 * returns array with the visibility options that are allowed for the current user.
378 *
379 * @param tx_languagevisibility_language $language
380 * @param bool $isOverlay
381 * @param null $element
382 * @return array
383 */
384 public static function getAvailableOptionsForLanguage(tx_languagevisibility_language $language, $isOverlay = FALSE, $element = NULL) {
385
386 $element = $element === NULL ? self::getContextElement('pages', self::_guessCurrentPid()) : $element;
387
388 $elementSupportsInheritance = $element->supportsInheritance();
389
390 $uid = $language->getUid();
391 $select = array();
392 $useInheritance = ($elementSupportsInheritance && self::isInheritanceEnabled());
393
394 if (! $isOverlay) {
395 if ($uid == 0) {
396 $select['-'] = '-';
397 $select['yes'] = 'yes';
398 $select['no'] = 'no';
399 if ($useInheritance) {
400 $select['no+'] = 'no+';
401 }
402 } else {
403 $select['-'] = '-';
404 $select['yes'] = 'yes';
405 $select['no'] = 'no';
406 if ($useInheritance) {
407 $select['no+'] = 'no+';
408 }
409 $select['t'] = 't';
410 $select['f'] = 'f';
411 }
412
413 //check permissions, if user has no permission only no for the language is allowed
414 // if the user has permissions for languages that act as fallbacklanguage: then the languages that falls back can have "-" in the options!
415 if (! $GLOBALS['BE_USER']->checkLanguageAccess($uid)) {
416
417 //check if the language falls back to one of the languages the user has permissions:
418 $isInFallback = FALSE;
419 $fallbacks = $language->getFallbackOrder($element);
420 foreach ( $fallbacks as $lId ) {
421 if ($GLOBALS['BE_USER']->checkLanguageAccess($lId)) {
422 $isInFallback = TRUE;
423 continue;
424 }
425 }
426 $select = array();
427 if ($isInFallback) {
428 $select['-'] = '-';
429 }
430
431 if ($uid != 0 && self::isTranslatedAsDefaultEnabled()) {
432 $select['t'] = 't';
433 }
434 $select['no'] = 'no';
435 if ($useInheritance) {
436 $select['no+'] = 'no+';
437 }
438 }
439 } else {
440 //overlays elements can only have "force to no" or "force to no inherited"
441 $select['-'] = '-';
442 $select['no'] = 'no';
443 if ($useInheritance) {
444 $select['no+'] = 'no+';
445 }
446 }
447
448 /**
449 * Get translations of labels from the locallang file
450 */
451 if (is_object($GLOBALS['LANG'])) {
452 //get value from locallang:
453 foreach ( $select as $k => $v ) {
454 $select[$k] = $GLOBALS['LANG']->sl('LLL:EXT:languagevisibility/locallang_db.xml:tx_languagevisibility_visibility.I.' . $v);
455 }
456 }
457
458 return $select;
459 }
460
461 /**
462 * @return mixed
463 */
464 protected static function _guessCurrentPid() {
465 return t3lib_div::_GP('id');
466 }
467
468 /**
469 * This method is used to create an visibility array with the default settings
470 * for all languages.
471 *
472 * @return array
473 */
474 public static function getDefaultVisibilityArray() {
475 /* @var $languageRep tx_languagevisibility_languagerepository */
476 $languageRep = t3lib_div::makeInstance('tx_languagevisibility_languagerepository');
477 $languageList = $languageRep->getLanguages();
478 $default = array();
479 foreach ( $languageList as $language ) {
480 $options = self::getAvailableOptionsForLanguage($language);
481 $default[$language->getUid()] = array_shift(array_keys($options));
482
483 }
484 return $default;
485 }
486
487 /**
488 * This method is used to get the table where original elements of the
489 * given table are stored.
490 *
491 * @param string $table
492 * @return string
493 */
494 public static function getOriginalTableOfTranslation($table) {
495 $translationTable = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
496 if ($translationTable != '') {
497 return $translationTable;
498 } else {
499 return $table;
500 }
501 }
502
503 /**
504 * This method is used to determine the original uid of a translation
505 *
506 * @param array $row
507 * @param string $table
508 * @return string
509 */
510 public static function getOriginalUidOfTranslation($row, $table) {
511 if (is_array($row) && is_array($GLOBALS['TCA'])) {
512 return $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']];
513 } else {
514 return 0;
515 }
516 }
517 }