Fixed bug #539: lang-children "get lost"(should be deleted) when deleting parent...
authorRupert Germann <rupi@gmx.li>
Tue, 20 Oct 2009 19:36:40 +0000 (19:36 +0000)
committerRupert Germann <rupi@gmx.li>
Tue, 20 Oct 2009 19:36:40 +0000 (19:36 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@6192 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_befunc.php
t3lib/class.t3lib_tcemain.php
t3lib/class.t3lib_userauthgroup.php
typo3/alt_clickmenu.php
typo3/class.db_list_extra.inc
typo3/sysext/cms/layout/class.tx_cms_layout.php
typo3/sysext/lang/locallang_core.xml

index 5c99359..8b09baf 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,7 @@
 
 2009-10-20  Rupert Germann  <rupi@gmx.li>
 
+       * Fixed bug #539: lang-children "get lost"(should be deleted) when deleting parent-record in default language (thanks to Tolleiv Nietsch)
        * Fixed bug #10081: t3lib_div must not die if a locallang file is not found (thanks to Franz Holzinger)
        * Fixed bug #12194: The filetree does not show whether a folder is write protected
 
index 0ff630f..e03cdb3 100644 (file)
@@ -3530,7 +3530,30 @@ final class t3lib_BEfunc {
        }
 
 
+       /**
+        * 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 9fd11d3..2b4b982 100644 (file)
@@ -4014,6 +4014,7 @@ class t3lib_TCEmain       {
                        } else {
                                // Otherwise, try to delete by versioning:
                                $this->versionizeRecord($table,$id,'DELETED!',TRUE);
+                               $this->deleteL10nOverlayRecords($table, $id);
                        }
                }
        }
@@ -4089,7 +4090,7 @@ class t3lib_TCEmain       {
                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 @@ class t3lib_TCEmain      {
                                                        // 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 @@ class t3lib_TCEmain       {
 
                                                        // 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 @@ class t3lib_TCEmain      {
                }
        }
 
+       /**
+        * 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 537f37c..32dc2fb 100644 (file)
@@ -538,6 +538,39 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        }
 
        /**
+        * 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 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
         * @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 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                                        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 d3a6ed5..e6e67fa 100644 (file)
@@ -727,7 +727,10 @@ class clickMenu {
                $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';
                }
index 94502a0..c06f596 100644 (file)
@@ -1244,7 +1244,8 @@ class localRecordList extends recordList {
                                        $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']='<a href="#" onclick="'.htmlspecialchars('if (confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning').' "'. $title.'" '.$refCountMsg).')) {jumpToUrl(\''.$SOBE->doc->issueCommand($params,-1).'\');} return false;').'">'.
                                                        '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$LANG->getLL('delete',1).'" alt="" />'.
                                                        '</a>';
index 7708353..a50cb80 100755 (executable)
@@ -1623,7 +1623,9 @@ class tx_cms_layout extends recordList {
 
                                        // Delete
                                $params='&cmd[tt_content]['.$row['uid'].'][delete]=1';
-                               $out.='<a href="'.htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)).'" onclick="'.htmlspecialchars('return confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->getLL('deleteWarning')).');').'">'.
+                               $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.='<a href="'.htmlspecialchars($GLOBALS['SOBE']->doc->issueCommand($params)).'" onclick="'.htmlspecialchars('return confirm('. $confirm .');').'">'.
                                                '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/garbage.gif','width="11" height="12"').' title="'.$GLOBALS['LANG']->getLL('deleteItem',1).'" alt="" />'.
                                                '</a>';
 
index 292b24e..5f7fc07 100755 (executable)
@@ -112,6 +112,7 @@ Do you want to continue WITHOUT saving?</label>
                        <label index="ver.swapPage">Publish this version of the page including content</label>
                        <label index="TYPO3_Element_Browser">TYPO3 Element Browser</label>
                        <label index="labels.referencesToRecord">(There are %s reference(s) to this record!)</label>
+                       <label index="labels.translationsOfRecord">(This record has %s translation(s) which will be deleted, too!)</label>
                        <label index="show_item.php.viewItem">View Item</label>
                        <label index="show_item.php.referencesToThisItem">References to this item:</label>
                        <label index="show_item.php.referencesFromThisItem">References from this item:</label>