Todays catch
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / web_info / class.tx_cms_webinfo_lang.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
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 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
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 * Contains a class with functions for page related overview of translations.
29 *
30 * $Id$
31 *
32 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
33 */
34 /**
35 * [CLASS/FUNCTION INDEX of SCRIPT]
36 *
37 *
38 *
39 * 65: class tx_cms_webinfo_lang extends t3lib_extobjbase
40 * 72: function modMenu()
41 * 89: function main()
42 * 156: function renderL10nTable(&$tree)
43 * 320: function getSystemLanguages()
44 * 342: function getLangStatus($pageId, $langId)
45 * 369: function getContentElementCount($pageId,$sysLang)
46 *
47 * TOTAL FUNCTIONS: 6
48 * (This index is automatically created/updated by the extension "extdeveval")
49 *
50 */
51
52 require_once(PATH_t3lib.'class.t3lib_pagetree.php');
53 require_once(PATH_t3lib.'class.t3lib_extobjbase.php');
54
55
56
57
58 /**
59 * Class for displaying translation status of pages in the tree.
60 *
61 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
62 * @package TYPO3
63 * @subpackage tx_cms
64 */
65 class tx_cms_webinfo_lang extends t3lib_extobjbase {
66
67 /**
68 * Returns the menu array
69 *
70 * @return array
71 */
72 function modMenu() {
73 global $LANG;
74
75 $menuArray = array (
76 'depth' => array(
77 1 => $LANG->getLL('depth_1'),
78 2 => $LANG->getLL('depth_2'),
79 3 => $LANG->getLL('depth_3')
80 ),
81 'details' => ''
82 );
83
84 // Languages:
85 $lang = $this->getSystemLanguages();
86 $menuArray['lang']=array(
87 0 => '[All]'
88 );
89 foreach($lang as $langRec) {
90 $menuArray['lang'][$langRec['uid']] = $langRec['title'];
91 }
92
93 return $menuArray;
94 }
95
96 /**
97 * MAIN function for page information of localization
98 *
99 * @return string Output HTML for the module.
100 */
101 function main() {
102 global $BACK_PATH,$LANG,$SOBE;
103
104 if ($this->pObj->id) {
105 $theOutput = '';
106
107 // Depth selector:
108 $h_func = t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[depth]',$this->pObj->MOD_SETTINGS['depth'],$this->pObj->MOD_MENU['depth'],'index.php');
109 $h_func.= t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[lang]',$this->pObj->MOD_SETTINGS['lang'],$this->pObj->MOD_MENU['lang'],'index.php');
110 $h_func.= t3lib_BEfunc::getFuncCheck($this->pObj->id,'SET[details]',$this->pObj->MOD_SETTINGS['details'],'index.php').' Details';
111 $theOutput.= $h_func;
112
113 // Add CSH:
114 $theOutput.= t3lib_BEfunc::cshItem('_MOD_web_info','lang',$GLOBALS['BACK_PATH'],'|<br/>');
115
116 // Showing the tree:
117 // Initialize starting point of page tree:
118 $treeStartingPoint = intval($this->pObj->id);
119 $treeStartingRecord = t3lib_BEfunc::getRecord('pages', $treeStartingPoint);
120 t3lib_BEfunc::workspaceOL('pages',$treeStartingRecord);
121 $depth = $this->pObj->MOD_SETTINGS['depth'];
122
123 // Initialize tree object:
124 $tree = t3lib_div::makeInstance('t3lib_pageTree');
125 $tree->init('AND '.$GLOBALS['BE_USER']->getPagePermsClause(1));
126 $tree->addField('l18n_cfg');
127
128 // Creating top icon; the current page
129 $HTML = t3lib_iconWorks::getIconImage('pages', $treeStartingRecord, $GLOBALS['BACK_PATH'],'align="top"');
130 $tree->tree[] = array(
131 'row' => $treeStartingRecord,
132 'HTML'=>$HTML
133 );
134
135 // Create the tree from starting point:
136 $tree->getTree($treeStartingPoint, $depth, '');
137 #debug($tree->tree);
138
139 // Add CSS needed:
140 $css_content = '
141 TABLE#langTable {
142 margin-top: 10px;
143 }
144 TABLE#langTable TR TD {
145 padding-left : 2px;
146 padding-right : 2px;
147 white-space: nowrap;
148 }
149 TD.c-blocked { background-color: red; }
150 TD.c-ok { background-color: #669966; }
151 TD.c-fallback { }
152 TD.c-leftLine {border-left: 2px solid black; }
153 .bgColor5 { font-weight: bold; }
154 ';
155 $marker = '/*###POSTCSSMARKER###*/';
156 $this->pObj->content = str_replace($marker,$css_content.chr(10).$marker,$this->pObj->content);
157
158 // Render information table:
159 $theOutput.= $this->renderL10nTable($tree);
160 }
161
162 return $theOutput;
163 }
164
165 /**
166 * Rendering the localization information table.
167 *
168 * @param array The Page tree data
169 * @return string HTML for the localization information table.
170 */
171 function renderL10nTable(&$tree) {
172 global $LANG;
173
174 // System languages retrieved:
175 $languages = $this->getSystemLanguages();
176
177 // Title length:
178 $titleLen = $GLOBALS['BE_USER']->uc['titleLen'];
179
180 // Put together the TREE:
181 $output = '';
182 $newOL_js = array();
183 $langRecUids = array();
184 foreach($tree->tree as $data) {
185 $tCells = array();
186 $langRecUids[0][] = $data['row']['uid'];
187
188 // Page icons / titles etc.
189 $tCells[] = '<td'.($data['row']['_CSSCLASS'] ? ' class="'.$data['row']['_CSSCLASS'].'"' : '').'>'.
190 $data['HTML'].
191 htmlspecialchars(t3lib_div::fixed_lgd_cs($data['row']['title'],$titleLen)).
192 (strcmp($data['row']['nav_title'],'') ? ' [Nav: <em>'.htmlspecialchars(t3lib_div::fixed_lgd_cs($data['row']['nav_title'],$titleLen)).'</em>]' : '').
193 '</td>';
194
195 // DEFAULT language:
196 // "View page" link is created:
197 $viewPageLink= '<a href="#" onclick="'.
198 htmlspecialchars(t3lib_BEfunc::viewOnClick($data['row']['uid'],$GLOBALS['BACK_PATH'],'','','','&L=###LANG_UID###')).'">'.
199 '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/zoom.gif','width="12" height="12"').' title="'.$LANG->getLL('lang_renderl10n_viewPage','1').'" border="0" alt="" />'.
200 '</a>';
201 $status = $data['row']['l18n_cfg']&1 ? 'c-blocked' : 'c-ok';
202
203 // Create links:
204 $info = '';
205 $editUid = $data['row']['uid'];
206 $params = '&edit[pages]['.$editUid.']=edit';
207 $info.= '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$GLOBALS['BACK_PATH'])).'">'.
208 '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('lang_renderl10n_editDefaultLanguagePage','1').'" border="0" alt="" />'.
209 '</a>';
210 $info.= '<a href="#" onclick="'.htmlspecialchars('top.loadEditId('.intval($data['row']['uid']).',"&SET[language]=0"); return false;').'">'.
211 '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/edit_page.gif','width="12" height="12"').' title="'.$LANG->getLL('lang_renderl10n_editPage','1').'" border="0" alt="" />'.
212 '</a>';
213 $info.= str_replace('###LANG_UID###','0',$viewPageLink);
214
215 $info.= '&nbsp;';
216 $info.= $data['row']['l18n_cfg']&1 ? '<span title="'.$LANG->sL('LLL:EXT:cms/locallang_tca.php:pages.l18n_cfg.I.1','1').'">D</span>' : '&nbsp;';
217 $info.= t3lib_div::hideIfNotTranslated($data['row']['l18n_cfg']) ? '<span title="'.$LANG->sL('LLL:EXT:cms/locallang_tca.php:pages.l18n_cfg.I.2','1').'">N</span>' : '&nbsp;';
218
219 // Put into cell:
220 $tCells[] = '<td class="'.$status.' c-leftLine">'.$info.'</td>';
221 $tCells[] = '<td class="'.$status.'" title="'.$LANG->getLL('lang_renderl10n_CEcount','1').'" align="center">'.$this->getContentElementCount($data['row']['uid'],0).'</td>';
222
223 // Traverse system languages:
224 foreach($languages as $langRow) {
225 if ($this->pObj->MOD_SETTINGS['lang']==0 || (int)$this->pObj->MOD_SETTINGS['lang']===(int)$langRow['uid']) {
226 $row = $this->getLangStatus($data['row']['uid'], $langRow['uid']);
227 $info = '';
228
229 if (is_array($row)) {
230 $langRecUids[$langRow['uid']][] = $row['uid'];
231 $status = $row['_HIDDEN'] ? (t3lib_div::hideIfNotTranslated($data['row']['l18n_cfg']) || $data['row']['l18n_cfg']&1 ? 'c-blocked' : 'c-fallback') : 'c-ok';
232 $icon = t3lib_iconWorks::getIconImage(
233 'pages_language_overlay',
234 $row,
235 $GLOBALS['BACK_PATH'],
236 'align="top" class="c-recIcon"'
237 );
238
239 $info = $icon.
240 htmlspecialchars(t3lib_div::fixed_lgd_cs($row['title'],$titleLen)).
241 (strcmp($row['nav_title'],'') ? ' [Nav: <em>'.htmlspecialchars(t3lib_div::fixed_lgd_cs($row['nav_title'],$titleLen)).'</em>]' : '').
242 ($row['_COUNT']>1 ? '<div>'.$LANG->getLL('lang_renderl10n_badThingThereAre','1').'</div>':'');
243 $tCells[] = '<td class="'.$status.' c-leftLine">'.
244 $info.
245 ($this->pObj->MOD_SETTINGS['details'] ? $this->getLocalizedElementInfo($data['row']['uid'],$langRow['uid']) : '').
246 '</td>';
247
248 // Edit whole record:
249 $info = '';
250 $editUid = $row['uid'];
251 $params = '&edit[pages_language_overlay]['.$editUid.']=edit';
252 $info.= '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$GLOBALS['BACK_PATH'])).'">'.
253 '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('lang_renderl10n_editLanguageOverlayRecord','1').'" border="0" alt="" />'.
254 '</a>';
255
256 $info.= '<a href="#" onclick="'.htmlspecialchars('top.loadEditId('.intval($data['row']['uid']).',"&SET[language]='.$langRow['uid'].'"); return false;').'">'.
257 '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/edit_page.gif','width="12" height="12"').' title="'.$LANG->getLL('lang_renderl10n_editPageLang','1').'" border="0" alt="" />'.
258 '</a>';
259 $info.= str_replace('###LANG_UID###',$langRow['uid'],$viewPageLink);
260
261 $tCells[] = '<td class="'.$status.'">'.$info.'</td>';
262 $tCells[] = '<td class="'.$status.'" title="'.$LANG->getLL('lang_renderl10n_CEcount','1').'" align="center">'.$this->getContentElementCount($data['row']['uid'],$langRow['uid']).'</td>';
263 } else {
264 $status = t3lib_div::hideIfNotTranslated($data['row']['l18n_cfg']) || $data['row']['l18n_cfg']&1 ? 'c-blocked' : 'c-fallback';
265 $tCells[] = '<td class="'.$status.' c-leftLine">&nbsp;</td>';
266 $tCells[] = '<td class="'.$status.'">&nbsp;</td>';
267
268 $info = '';
269 $info.= '<input type="checkbox" name="newOL['.$langRow['uid'].']['.$data['row']['uid'].']" value="1" />';
270 $newOL_js[$langRow['uid']].= '
271 +(document.webinfoForm[\'newOL['.$langRow['uid'].']['.$data['row']['uid'].']\'].checked ? \'&edit[pages_language_overlay]['.$data['row']['uid'].']=new\' : \'\')
272 ';
273 $tCells[] = '<td class="'.$status.'">'.$info.'</td>';
274 }
275 }
276 }
277
278 $output.= '
279 <tr class="bgColor4">
280 '.implode('
281 ',$tCells).'
282 </tr>';
283 }
284
285 // Put together HEADER:
286 $tCells = array();
287 $tCells[] = '<td>'.$LANG->getLL('lang_renderl10n_page','1').':</td>';
288
289 if (is_array($langRecUids[0])) {
290 $params = '&edit[pages]['.implode(',',$langRecUids[0]).']=edit&columnsOnly=title,nav_title,l18n_cfg,hidden';
291 $editIco = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$GLOBALS['BACK_PATH'])).'">
292 <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('lang_renderl10n_editPageHeaders','1').'" border="0" alt="" />
293 </a>';
294 } else $editIco = '';
295 $tCells[] = '<td class="c-leftLine" colspan="2">'.
296 $LANG->getLL('lang_renderl10n_default','1').':'.
297 $editIco.
298 '</td>';
299
300 foreach($languages as $langRow) {
301 if ($this->pObj->MOD_SETTINGS['lang']==0 || (int)$this->pObj->MOD_SETTINGS['lang']===(int)$langRow['uid']) {
302 // Title:
303 $tCells[] = '<td class="c-leftLine">'.htmlspecialchars($langRow['title']).'</td>';
304
305 // Edit language overlay records:
306 if (is_array($langRecUids[$langRow['uid']])) {
307 $params = '&edit[pages_language_overlay]['.implode(',',$langRecUids[$langRow['uid']]).']=edit&columnsOnly=title,nav_title,hidden';
308 $tCells[] = '<td><a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$GLOBALS['BACK_PATH'])).'">
309 <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/edit2.gif','width="11" height="12"').' title="'.$LANG->getLL('lang_renderl10n_editLangOverlays','1').'" border="0" alt="" />
310 </a></td>';
311 } else {
312 $tCells[] = '<td>&nbsp;</td>';
313 }
314
315 // Create new overlay records:
316 $params = "'".$newOL_js[$langRow['uid']]."+'&columnsOnly=title,hidden,sys_language_uid&defVals[pages_language_overlay][sys_language_uid]=".$langRow['uid'];
317 $tCells[] = '<td><a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$GLOBALS['BACK_PATH'])).'">
318 <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/new_el.gif','width="11" height="12"').' title="'.$LANG->getLL('lang_getlangsta_createNewTranslationHeaders','1').'" border="0" alt="" />
319 </a></td>';
320 }
321 }
322
323 $output = '
324 <tr class="bgColor5">
325 '.implode('
326 ',$tCells).'
327 </tr>'.$output;
328
329 $output = '
330
331 <table border="0" cellspacing="0" cellpadding="0" id="langTable">'.$output.'
332 </table>';
333
334 return $output;
335 }
336
337 /**
338 * Selects all system languages (from sys_language)
339 *
340 * @return array System language records in an array.
341 */
342 function getSystemLanguages() {
343 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
344 '*',
345 'sys_language',
346 '1'.t3lib_BEfunc::deleteClause('sys_language')
347 );
348
349 $outputArray = array();
350 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
351 $outputArray[] = $row;
352 }
353
354 return $outputArray;
355 }
356
357 /**
358 * Get an alternative language record for a specific page / language
359 *
360 * @param integer Page ID to look up for.
361 * @param integer Language UID to select for.
362 * @return array pages_languages_overlay record
363 */
364 function getLangStatus($pageId, $langId) {
365 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
366 '*',
367 'pages_language_overlay',
368 'pid='.intval($pageId).
369 ' AND sys_language_uid='.intval($langId).
370 t3lib_BEfunc::deleteClause('pages_language_overlay')
371 );
372
373 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
374 if (is_array($row)) {
375 t3lib_BEfunc::workspaceOL('pages_language_overlay',$row);
376 $row['_COUNT'] = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
377 $row['_HIDDEN'] = $row['hidden'] ||
378 (intval($row['endtime']) > 0 && intval($row['endtime']) < time()) ||
379 (time() < intval($row['starttime']));
380 }
381
382 return $row;
383 }
384
385 /**
386 * Counting content elements for a single language on a page.
387 *
388 * @param integer Page id to select for.
389 * @param integer Sys language uid
390 * @return integer Number of content elements from the PID where the language is set to a certain value.
391 */
392 function getLocalizedElementInfo($pageId,$sysLang) {
393 global $TCA;
394
395 $info = '<hr/>';
396 foreach($TCA as $table => $cfg) {
397 if ($table!='pages' && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField']) {
398 # $info.='<h3>'.$table.'</h3>';
399 if ($TCA[$table]['ctrl']['transOrigPointerTable']) {
400 #$info.='Table "'.$table.'" is skipped because it had a transOrigPointerTable set which is not supported - yet.';
401 } else {
402
403 // First, select all records that are default language OR international:
404 $allRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
405 '*',
406 $table,
407 'pid='.intval($pageId).
408 ' AND '.$TCA[$table]['ctrl']['languageField'].'<=0'.
409 t3lib_BEfunc::deleteClause($table)
410 );
411 if (count($allRows)) {
412 $info.='<h3>'.$table.'</h3>';
413
414 $info.='[<b>'.$TCA[$table]['ctrl']['languageField'].'</b>]';
415 $info.='[<b>'.$TCA[$table]['ctrl']['transOrigPointerField'].'</b>]';
416 $info.='[<b>'.$TCA[$table]['ctrl']['transOrigDiffSourceField'].'</b>]';
417
418 // Now, for each record, look for localization:
419 $translationsUids = array(0);
420 foreach($allRows as $row) {
421 $info.='UID:'.$row['uid'].'/lang:'.$row[$TCA[$table]['ctrl']['languageField']].' has translations:';
422 $translations = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
423 '*',
424 $table,
425 'pid='.intval($pageId).
426 ' AND '.$TCA[$table]['ctrl']['languageField'].'='.intval($sysLang).
427 ' AND '.$TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($row['uid']).
428 t3lib_BEfunc::deleteClause($table)
429 );
430
431 foreach($translations as $c => $tr) {
432 $info.=($c>0 ? 'UPS!!':'').'['.$tr['uid'].'],';
433 $translationsUids[] = $tr['uid'];
434 }
435
436
437
438 $info.='<br/>';
439 }
440
441 // Look for "lost" translations
442 $lostTranslations = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
443 'uid',
444 $table,
445 'pid='.intval($pageId).
446 ' AND '.$TCA[$table]['ctrl']['languageField'].'='.intval($sysLang).
447 ' AND uid NOT IN ('.implode(',',$translationsUids).')'.
448 t3lib_BEfunc::deleteClause($table)
449 );
450 if (count($lostTranslations)) {
451 $info.=t3lib_div::view_array($lostTranslations);
452 }
453 }
454 }
455 }
456 }
457 return $info;
458 }
459
460 /**
461 * Counting content elements for a single language on a page.
462 *
463 * @param integer Page id to select for.
464 * @param integer Sys language uid
465 * @return integer Number of content elements from the PID where the language is set to a certain value.
466 */
467 function getContentElementCount($pageId,$sysLang) {
468 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
469 'count(*)',
470 'tt_content',
471 'pid='.intval($pageId).
472 ' AND sys_language_uid='.intval($sysLang).
473 t3lib_BEfunc::deleteClause('tt_content')
474 );
475
476 list($count) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
477 return $count ? $count : '-';
478 }
479 }
480
481
482 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cms/web_info/class.tx_cms_webinfo_lang.php']) {
483 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cms/web_info/class.tx_cms_webinfo_lang.php']);
484 }
485 ?>