Index: t3lib/class.t3lib_tcemain.php =================================================================== --- t3lib/class.t3lib_tcemain.php (revision 6163) +++ t3lib/class.t3lib_tcemain.php (working copy) @@ -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: t3lib/class.t3lib_userauthgroup.php =================================================================== --- t3lib/class.t3lib_userauthgroup.php (revision 6163) +++ t3lib/class.t3lib_userauthgroup.php (working copy) @@ -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'], + '', //AND '.$GLOBALS['TCA'][$table]['ctrl']['languageField'].'>0 '.($andWhereClause ? ' '.$andWhereClause : ''), + '', + '', + '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!';