Index: t3lib/class.t3lib_befunc.php =================================================================== --- t3lib/class.t3lib_befunc.php (Revision 6177) +++ t3lib/class.t3lib_befunc.php (Arbeitskopie) @@ -3521,7 +3521,30 @@ } + /** + * Counting translations of records + * + * @param string Table name + * @param string Reference: the record's uid + * @param string Message with %s, eg. "This record has %s translation(s) which will be deleted, too!" + * @return string Output string (or integer count value if no msg string specified) + */ + public static function translationCount($table, $ref, $msg = '') { + if ($table != 'pages' && + $GLOBALS['TCA'][$table]['ctrl']['languageField'] && + $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] + && !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']) { + $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows( + '*', + $table, + $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . '=' . intval($ref) . + ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['languageField'] . '!=0' . + ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['delete'] . '=0' + ); + } + return ($count ? ($msg ? sprintf($msg, $count) : $count) : ''); + } Index: t3lib/class.t3lib_userauthgroup.php =================================================================== --- t3lib/class.t3lib_userauthgroup.php (Revision 6177) +++ t3lib/class.t3lib_userauthgroup.php (Arbeitskopie) @@ -538,6 +538,39 @@ } /** + * Check if user has access to all existing localizations for a certain record + * + * @param array $record + * @return boolean + */ + function checkFullLanguagesAccess($table, $record) { + $recordLocalizationAccess = $this->checkLanguageAccess(0); + if ($recordLocalizationAccess && t3lib_BEfunc::isTableLocalizable($table)) { + + $pointerField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']; + + $recordLocalizations = t3lib_BEfunc::getRecordsByField( + $table, + $pointerField, + $record[$pointerField]>0 ? $record[$pointerField] : $record['uid'], + '', + '', + '', + '1' + ); + + if(is_array($recordLocalizations)) { + foreach($recordLocalizations as $localization) { + $recordLocalizationAccess = $recordLocalizationAccess && $this->checkLanguageAccess( $localization[$GLOBALS['TCA'][$table]['ctrl']['languageField']]); + if (!$recordLocalizationAccess) break; + } + } + + } + return $recordLocalizationAccess; + } + + /** * Checking if a user has editing access to a record from a $TCA table. * The checks does not take page permissions and other "environmental" things into account. It only deal with record internals; If any values in the record fields disallows it. * For instance languages settings, authMode selector boxes are evaluated (and maybe more in the future). @@ -548,9 +581,10 @@ * @param mixed If integer, then this is the ID of the record. If Array this just represents fields in the record. * @param boolean Set, if testing a new (non-existing) record array. Will disable certain checks that doesn't make much sense in that context. * @param boolean Set, if testing a deleted record array. + * @param boolean Set, whenever access to all translations of the record is required * @return boolean True if OK, otherwise false */ - function recordEditAccessInternals($table, $idOrRow, $newRecord = FALSE, $deletedRecord = FALSE) { + function recordEditAccessInternals($table, $idOrRow, $newRecord = FALSE, $deletedRecord = FALSE, $checkFullLanguageAccess = FALSE) { global $TCA; if (isset($TCA[$table])) { @@ -578,6 +612,9 @@ if (!$this->checkLanguageAccess($idOrRow[$TCA[$table]['ctrl']['languageField']])) { $this->errorMsg = 'ERROR: Language was not allowed.'; return FALSE; + } elseif ($checkFullLanguageAccess && !$this->checkFullLanguagesAccess($table, $idOrRow)) { + $this->errorMsg = 'ERROR: Related/affected language was not allowed.'; + return FALSE; } } else { $this->errorMsg = 'ERROR: The "languageField" field named "'.$TCA[$table]['ctrl']['languageField'].'" was not found in testing record!'; Index: t3lib/class.t3lib_tcemain.php =================================================================== --- t3lib/class.t3lib_tcemain.php (Revision 6177) +++ t3lib/class.t3lib_tcemain.php (Arbeitskopie) @@ -4014,6 +4014,7 @@ } else { // Otherwise, try to delete by versioning: $this->versionizeRecord($table,$id,'DELETED!',TRUE); + $this->deleteL10nOverlayRecords($table, $id); } } } @@ -4089,7 +4090,7 @@ global $TCA; // Checking if there is anything else disallowing deleting the record by checking if editing is allowed - $mayEditAccess = $this->BE_USER->recordEditAccessInternals($table, $uid, FALSE, $undeleteRecord); + $mayEditAccess = $this->BE_USER->recordEditAccessInternals($table, $uid, FALSE, $undeleteRecord, TRUE); $uid = intval($uid); if ($TCA[$table] && $uid) { @@ -4119,6 +4120,11 @@ // before (un-)deleting this record, check for child records or references $this->deleteRecord_procFields($table, $uid, $undeleteRecord); $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields); + + // delete all l10n records aswell, impossible during undelete because it might bring too many records back to life + if (!$undeleteRecord) { + $this->deleteL10nOverlayRecords($table, $uid); + } } else { // Fetches all fields with flexforms and look for files to delete: @@ -4150,6 +4156,8 @@ // Delete the hard way...: $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid='.intval($uid)); + + $this->deleteL10nOverlayRecords($table, $uid); } $state = $undeleteRecord ? 1 : 3; // 1 means insert, 3 means delete @@ -4414,7 +4422,24 @@ } } + /** + * Find l10n-overlay records and perform the requested delete action for these records. + * + * @param string $table: Record Table + * @param string $uid: Record UID + * @return void + */ + function deleteL10nOverlayRecords($table, $uid) { + if ($table == 'pages') return; + t3lib_div::loadTCA($table); + $l10nRecords = t3lib_BEfunc::getRecordsByField($table, $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], $uid); + if (is_array($l10nRecords)) { + foreach($l10nRecords as $record) { + $this->deleteAction($table, intval($record['t3ver_oid']) > 0 ? intval($record['t3ver_oid']) : intval($record['uid'])); + } + } + } Index: typo3/sysext/lang/locallang_core.xml =================================================================== --- typo3/sysext/lang/locallang_core.xml (Revision 6177) +++ typo3/sysext/lang/locallang_core.xml (Arbeitskopie) @@ -112,6 +112,7 @@ + Index: typo3/sysext/cms/layout/class.tx_cms_layout.php =================================================================== --- typo3/sysext/cms/layout/class.tx_cms_layout.php (Revision 6177) +++ typo3/sysext/cms/layout/class.tx_cms_layout.php (Arbeitskopie) @@ -1623,7 +1623,9 @@ // Delete $params='&cmd[tt_content]['.$row['uid'].'][delete]=1'; - $out.=''. + $confirm = $GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning') . + t3lib_BEfunc::translationCount('tt_content', $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord'))); + $out.=''. 'backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$GLOBALS['LANG']->getLL('deleteItem',1).'" alt="" />'. ''; Index: typo3/class.db_list_extra.inc =================================================================== --- typo3/class.db_list_extra.inc (Revision 6177) +++ typo3/class.db_list_extra.inc (Arbeitskopie) @@ -1232,7 +1232,8 @@ $title = t3lib_div::slashJS(t3lib_div::fixed_lgd_cs($titleOrig, $this->fixedL), 1); $params = '&cmd['.$table.']['.$row['uid'].'][delete]=1'; - $refCountMsg = t3lib_BEfunc::referenceCount($table, $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.referencesToRecord'), count($this->references)); + $refCountMsg = t3lib_BEfunc::referenceCount($table, $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.referencesToRecord'), count($this->references)) . + t3lib_BEfunc::translationCount($table, $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord')) . ")"; $cells['delete']='doc->issueCommand($params,-1).'\');} return false;').'">'. 'backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$LANG->getLL('delete',1).'" alt="" />'. ''; Index: typo3/alt_clickmenu.php =================================================================== --- typo3/alt_clickmenu.php (Revision 6177) +++ typo3/alt_clickmenu.php (Arbeitskopie) @@ -727,7 +727,10 @@ $editOnClick=''; $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); if($GLOBALS['BE_USER']->jsConfirmation(4)) { - $conf = "confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'),$elInfo[0]).t3lib_BEfunc::referenceCount($table,$uid,' (There are %s reference(s) to this record!)')).")"; + $conf = "confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'),$elInfo[0]) . + t3lib_BEfunc::referenceCount($table,$uid,' (There are %s reference(s) to this record!)') . + t3lib_BEfunc::translationCount($table, $uid, ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord')) + ) . ")"; } else { $conf = '1==1'; }