TYPO3 CMS  TYPO3_7-6
TranslationStatusController.php
Go to the documentation of this file.
1 <?php
2 
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
23 
28 {
32  protected $iconFactory;
33 
37  public function __construct()
38  {
39  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
40  }
41 
47  public function modMenu()
48  {
49  $lang = $this->getLanguageService();
50  $menuArray = [
51  'depth' => [
52  0 => $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_0'),
53  1 => $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_1'),
54  2 => $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_2'),
55  3 => $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_3'),
56  4 => $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_4'),
57  999 => $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_infi')
58  ]
59  ];
60  // Languages:
61  $lang = $this->getSystemLanguages();
62  $menuArray['lang'] = [
63  0 => '[All]'
64  ];
65  foreach ($lang as $langRec) {
66  $menuArray['lang'][$langRec['uid']] = $langRec['title'];
67  }
68  return $menuArray;
69  }
70 
76  public function main()
77  {
78  $theOutput = $this->pObj->doc->header($this->getLanguageService()->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_title'));
79  if ($this->pObj->id) {
80  // Depth selector:
81  $theOutput .= '<div class="form-inline form-inline-spaced">';
82  $h_func = BackendUtility::getDropdownMenu($this->pObj->id, 'SET[depth]', $this->pObj->MOD_SETTINGS['depth'], $this->pObj->MOD_MENU['depth']);
83  $h_func .= BackendUtility::getDropdownMenu($this->pObj->id, 'SET[lang]', $this->pObj->MOD_SETTINGS['lang'], $this->pObj->MOD_MENU['lang']);
84  $theOutput .= $h_func;
85  // Add CSH:
86  $theOutput .= BackendUtility::cshItem('_MOD_web_info', 'lang', null, '<div class="form-group"><span class="btn btn-default btn-sm">|</span></div><br />');
87  $theOutput .= '</div>';
88  // Showing the tree:
89  // Initialize starting point of page tree:
90  $treeStartingPoint = (int)$this->pObj->id;
91  $treeStartingRecord = BackendUtility::getRecordWSOL('pages', $treeStartingPoint);
92  $depth = $this->pObj->MOD_SETTINGS['depth'];
93  // Initialize tree object:
94  $tree = GeneralUtility::makeInstance(PageTreeView::class);
95  $tree->init('AND ' . $this->getBackendUser()->getPagePermsClause(1));
96  $tree->addField('l18n_cfg');
97  // Creating top icon; the current page
98  $HTML = $this->iconFactory->getIconForRecord('pages', $treeStartingRecord, Icon::SIZE_SMALL)->render();
99  $tree->tree[] = [
100  'row' => $treeStartingRecord,
101  'HTML' => $HTML
102  ];
103  // Create the tree from starting point:
104  if ($depth) {
105  $tree->getTree($treeStartingPoint, $depth, '');
106  }
107  // Render information table:
108  $theOutput .= $this->renderL10nTable($tree);
109  }
110  return $theOutput;
111  }
112 
119  public function renderL10nTable(&$tree)
120  {
121  $lang = $this->getLanguageService();
122  // System languages retrieved:
123  $languages = $this->getSystemLanguages();
124  // Title length:
125  $titleLen = $this->getBackendUser()->uc['titleLen'];
126  // Put together the TREE:
127  $output = '';
128  $newOL_js = [];
129  $langRecUids = [];
130  foreach ($tree->tree as $data) {
131  $tCells = [];
132  $langRecUids[0][] = $data['row']['uid'];
133  // Page icons / titles etc.
134  $tCells[] = '<td' . ($data['row']['_CSSCLASS'] ? ' class="' . $data['row']['_CSSCLASS'] . '"' : '') . '>' .
135  ($data['depthData'] ?: '') .
136  BackendUtility::wrapClickMenuOnIcon($data['HTML'], 'pages', $data['row']['uid']) .
137  '<a href="#" onclick="' . htmlspecialchars(
138  'top.loadEditId(' . (int)$data['row']['uid'] . ',"&SET[language]=0"); return false;'
139  ) . '" title="' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPage') . '">' .
140  htmlspecialchars(GeneralUtility::fixed_lgd_cs($data['row']['title'], $titleLen)) .
141  '</a>' .
142  ((string)$data['row']['nav_title'] !== '' ? ' [Nav: <em>' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($data['row']['nav_title'], $titleLen)) . '</em>]' : '') .
143  '</td>';
144  // DEFAULT language:
145  // "View page" link is created:
146  $viewPageLink = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick(
147  $data['row']['uid'], '', '', '', '', '&L=###LANG_UID###')
148  ) . '" class="btn btn-default" title="' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_viewPage') . '">' .
149  $this->iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL)->render() . '</a>';
150  $status = GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? 'danger' : 'success';
151  // Create links:
152  $editUrl = BackendUtility::getModuleUrl('record_edit', [
153  'edit' => [
154  'pages' => [
155  $data['row']['uid'] => 'edit'
156  ]
157  ],
158  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
159  ]);
160  $info = '<a href="' . htmlspecialchars($editUrl)
161  . '" class="btn btn-default" title="' . $lang->sL(
162  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editDefaultLanguagePage'
163  ) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
164  $info .= str_replace('###LANG_UID###', '0', $viewPageLink);
165  $info .= '&nbsp;';
166  $info .= GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? '<span title="' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.l18n_cfg.I.1', true) . '">D</span>' : '&nbsp;';
167  $info .= GeneralUtility::hideIfNotTranslated($data['row']['l18n_cfg']) ? '<span title="' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.l18n_cfg.I.2', true) . '">N</span>' : '&nbsp;';
168  // Put into cell:
169  $tCells[] = '<td class="' . $status . ' col-border-left"><div class="btn-group">' . $info . '</div></td>';
170  $tCells[] = '<td class="' . $status . '" title="' . $lang->sL(
171  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_CEcount'
172  ) . '" align="center">' . $this->getContentElementCount($data['row']['uid'], 0) . '</td>';
173  $modSharedTSconfig = BackendUtility::getModTSconfig($data['row']['uid'], 'mod.SHARED');
174  $disableLanguages = isset($modSharedTSconfig['properties']['disableLanguages']) ? GeneralUtility::trimExplode(',', $modSharedTSconfig['properties']['disableLanguages'], true) : [];
175  // Traverse system languages:
176  foreach ($languages as $langRow) {
177  if ($this->pObj->MOD_SETTINGS['lang'] == 0 || (int)$this->pObj->MOD_SETTINGS['lang'] === (int)$langRow['uid']) {
178  $row = $this->getLangStatus($data['row']['uid'], $langRow['uid']);
179  $info = '';
180  if (is_array($row)) {
181  $langRecUids[$langRow['uid']][] = $row['uid'];
182  $status = $row['_HIDDEN'] ? (GeneralUtility::hideIfNotTranslated($data['row']['l18n_cfg']) || GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? 'danger' : '') : 'success';
183  $icon = $this->iconFactory->getIconForRecord('pages_language_overlay', $row, Icon::SIZE_SMALL)->render();
184  $info = $icon . htmlspecialchars(
185  GeneralUtility::fixed_lgd_cs($row['title'], $titleLen)
186  ) . ((string)$row['nav_title'] !== '' ? ' [Nav: <em>' . htmlspecialchars(
187  GeneralUtility::fixed_lgd_cs($row['nav_title'], $titleLen)
188  ) . '</em>]' : '') . ($row['_COUNT'] > 1 ? '<div>' . $lang->sL(
189  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_badThingThereAre'
190  ) . '</div>' : '');
191  $tCells[] = '<td class="' . $status . ' col-border-left">' .
192  '<a href="#" onclick="' . htmlspecialchars(
193  'top.loadEditId(' . (int)$data['row']['uid'] . ',"&SET[language]=' . $langRow['uid'] . '"); return false;'
194  ) . '" title="' . $lang->sL(
195  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPageLang'
196  ) . '">' . $info . '</a></td>';
197  // Edit whole record:
198  // Create links:
199  $editUrl = BackendUtility::getModuleUrl('record_edit', [
200  'edit' => [
201  'pages_language_overlay' => [
202  $row['uid'] => 'edit'
203  ]
204  ],
205  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
206  ]);
207  $info = '<a href="' . htmlspecialchars($editUrl)
208  . '" class="btn btn-default" title="' . $lang->sL(
209  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editLanguageOverlayRecord'
210  ) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
211  $info .= str_replace('###LANG_UID###', $langRow['uid'], $viewPageLink);
212  $tCells[] = '<td class="' . $status . '"><div class="btn-group">' . $info . '</div></td>';
213  $tCells[] = '<td class="' . $status . '" title="' . $lang->sL(
214  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_CEcount'
215  ) . '" align="center">' . $this->getContentElementCount($data['row']['uid'], $langRow['uid']) . '</td>';
216  } else {
217  if (in_array($langRow['uid'], $disableLanguages)) {
218  // Language has been disabled for this page
219  $status = 'danger';
220  $info = '';
221  } else {
222  $status = GeneralUtility::hideIfNotTranslated($data['row']['l18n_cfg']) || GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? 'danger' : '';
223  $info = '<input type="checkbox" name="newOL[' . $langRow['uid'] . '][' . $data['row']['uid'] . ']" value="1" />';
224  $newOL_js[$langRow['uid']] .= '
225  +(document.webinfoForm['
226  . GeneralUtility::quoteJSvalue('newOL[' . $langRow['uid'] . '][' . $data['row']['uid'] . ']')
227  . '].checked ? '
228  . GeneralUtility::quoteJSvalue('&edit[pages_language_overlay][' . $data['row']['uid'] . ']=new')
229  . ' : \'\')
230  ';
231  }
232  $tCells[] = '<td class="' . $status . ' col-border-left">&nbsp;</td>';
233  $tCells[] = '<td class="' . $status . '">&nbsp;</td>';
234  $tCells[] = '<td class="' . $status . '">' . $info . '</td>';
235  }
236  }
237  }
238  $output .= '
239  <tr>
240  ' . implode('
241  ', $tCells) . '
242  </tr>';
243  }
244  // Put together HEADER:
245  $tCells = [];
246  $tCells[] = '<td>' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_page') . ':</td>';
247  if (is_array($langRecUids[0])) {
248  $editUrl = BackendUtility::getModuleUrl('record_edit', [
249  'edit' => [
250  'pages' => [
251  implode(',', $langRecUids[0]) => 'edit'
252  ]
253  ],
254  'columnsOnly' => 'title,nav_title,l18n_cfg,hidden',
255  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
256  ]);
257  $editIco = '<a href="' . htmlspecialchars($editUrl)
258  . '" class="btn btn-default" title="' . $lang->sL(
259  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPageProperties'
260  ) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
261  } else {
262  $editIco = '';
263  }
264  $tCells[] = '<td class="col-border-left" colspan="2">' . $lang->sL(
265  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_default'
266  ) . ':' . $editIco . '</td>';
267  foreach ($languages as $langRow) {
268  if ($this->pObj->MOD_SETTINGS['lang'] == 0 || (int)$this->pObj->MOD_SETTINGS['lang'] === (int)$langRow['uid']) {
269  // Title:
270  $tCells[] = '<td class="col-border-left">' . htmlspecialchars($langRow['title']) . '</td>';
271  // Edit language overlay records:
272  if (is_array($langRecUids[$langRow['uid']])) {
273  $editUrl = BackendUtility::getModuleUrl('record_edit', [
274  'edit' => [
275  'pages_language_overlay' => [
276  implode(',', $langRecUids[$langRow['uid']]) => 'edit'
277  ]
278  ],
279  'columnsOnly' => 'title,nav_title,hidden',
280  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
281  ]);
282  $editButton = '<a href="' . htmlspecialchars($editUrl)
283  . '" class="btn btn-default" title="' . $lang->sL(
284  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editLangOverlays'
285  ) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
286  } else {
287  $editButton = '';
288  }
289  // Create new overlay records:
290  $params = '&columnsOnly=title,hidden,sys_language_uid&overrideVals[pages_language_overlay][sys_language_uid]=' . $langRow['uid'];
292  if (!empty($newOL_js[$langRow['uid']])) {
293  $onClickArray = explode('?', $onClick, 2);
294  $lastElement = array_pop($onClickArray);
295  array_push($onClickArray, '\'' . $newOL_js[$langRow['uid']] . ' + \'&' . $lastElement);
296  $onClick = implode('?', $onClickArray);
297  }
298  $newButton = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($onClick)
299  . '" title="' . $lang->sL(
300  'LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_getlangsta_createNewTranslationHeaders'
301  ) . '">' . $this->iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render() . '</a>';
302 
303  $tCells[] = '<td class="btn-group">' . $editButton . $newButton . '</td>';
304  $tCells[] = '<td>&nbsp;</td>';
305  }
306  }
307 
308  $output =
309  '<div class="table-fit">' .
310  '<table class="table table-striped table-hover" id="langTable">' .
311  '<thead>' .
312  '<tr>' .
313  implode('', $tCells) .
314  '</tr>' .
315  '</thead>' .
316  '<tbody>' .
317  $output .
318  '</tbody>' .
319  '</table>' .
320  '</div>';
321  return $output;
322  }
323 
329  public function getSystemLanguages()
330  {
331  if (!$this->getBackendUser()->user['admin'] && $this->getBackendUser()->groupData['allowed_languages'] !== '') {
332  $allowed_languages = array_flip(explode(',', $this->getBackendUser()->groupData['allowed_languages']));
333  }
334  $res = $this->getDatabaseConnection()->exec_SELECTquery('*', 'sys_language', '1=1' . BackendUtility::deleteClause('sys_language'));
335  $outputArray = [];
336  while ($row = $this->getDatabaseConnection()->sql_fetch_assoc($res)) {
337  if (is_array($allowed_languages) && !empty($allowed_languages)) {
338  if (isset($allowed_languages[$row['uid']])) {
339  $outputArray[] = $row;
340  }
341  } else {
342  $outputArray[] = $row;
343  }
344  }
345  $this->getDatabaseConnection()->sql_free_result($res);
346  return $outputArray;
347  }
348 
356  public function getLangStatus($pageId, $langId)
357  {
358  $res = $this->getDatabaseConnection()->exec_SELECTquery(
359  '*',
360  'pages_language_overlay',
361  'pid=' . (int)$pageId .
362  ' AND sys_language_uid=' . (int)$langId .
363  BackendUtility::deleteClause('pages_language_overlay') .
364  BackendUtility::versioningPlaceholderClause('pages_language_overlay')
365  );
366  $row = $this->getDatabaseConnection()->sql_fetch_assoc($res);
367  BackendUtility::workspaceOL('pages_language_overlay', $row);
368  if (is_array($row)) {
369  $row['_COUNT'] = $this->getDatabaseConnection()->sql_num_rows($res);
370  $row['_HIDDEN'] = $row['hidden'] || (int)$row['endtime'] > 0 && (int)$row['endtime'] < $GLOBALS['EXEC_TIME'] || $GLOBALS['EXEC_TIME'] < (int)$row['starttime'];
371  }
372  return $row;
373  }
374 
382  public function getContentElementCount($pageId, $sysLang)
383  {
384  $count = $this->getDatabaseConnection()->exec_SELECTcountRows('uid', 'tt_content', 'pid=' . (int)$pageId . ' AND sys_language_uid=' . (int)$sysLang . BackendUtility::deleteClause('tt_content') . BackendUtility::versioningPlaceholderClause('tt_content'));
385  return $count ?: '-';
386  }
387 
393  protected function getLanguageService()
394  {
395  return $GLOBALS['LANG'];
396  }
397 
403  protected function getDatabaseConnection()
404  {
405  return $GLOBALS['TYPO3_DB'];
406  }
407 
413  protected function getBackendUser()
414  {
415  return $GLOBALS['BE_USER'];
416  }
417 }
static editOnClick($params, $_='', $requestUri='')
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static hideIfDefaultLanguage($localizationConfiguration)
static workspaceOL($table, &$row, $wsid=-99, $unsetMovePointers=false)
static hideIfNotTranslated($l18n_cfg_fieldValue)
static cshItem($table, $field, $_='', $wrap='')
static viewOnClick($pageUid, $backPath='', $rootLine=null, $anchorSection='', $alternativeUrl='', $additionalGetVars='', $switchFocus=true)
static fixed_lgd_cs($string, $chars, $appendString='...')
static wrapClickMenuOnIcon( $content, $table, $uid=0, $listFrame=true, $addParams='', $enDisItems='', $returnTagParameters=false)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static getRecordWSOL($table, $uid, $fields=' *', $where='', $useDeleteClause=true, $unsetMovePointers=false)
static deleteClause($table, $tableAlias='')
static getDropdownMenu($mainParams, $elementName, $currentValue, $menuItems, $script='', $addParams='')