[TASK] Compatibility with TYPO3 CMS 7 19/42819/2
authorFrancois Suter <francois@typo3.org>
Fri, 21 Aug 2015 15:37:18 +0000 (17:37 +0200)
committerFrancois Suter <francois@typo3.org>
Fri, 21 Aug 2015 15:38:40 +0000 (17:38 +0200)
Releases: 3.0
Resolves: #69244
Change-Id: I339c4fce882285829da091a949a76a0c59e925b0
Reviewed-on: http://review.typo3.org/42819
Reviewed-by: Francois Suter <francois@typo3.org>
Tested-by: Francois Suter <francois@typo3.org>
ChangeLog
Classes/OverlayEngine.php [new file with mode: 0644]
class.tx_overlays.php [deleted file]
ext_autoload.php [deleted file]
ext_emconf.php
ext_icon.gif [deleted file]
ext_icon.png [new file with mode: 0644]

index 8a4e97d..f6f3d3b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-08-21 Francois Suter (Cobweb)  <typo3@cobweb.ch>
+
+       * Moved to namespaces, verified compatibility with TYPO3 CMS 7, resolves #69244
+
 2014-05-09 Francois Suter (Cobweb)  <typo3@cobweb.ch>
 
        * Added method for returning a single record, resolves #56087
diff --git a/Classes/OverlayEngine.php b/Classes/OverlayEngine.php
new file mode 100644 (file)
index 0000000..e1f6304
--- /dev/null
@@ -0,0 +1,786 @@
+<?php
+namespace Cobweb\Overlays;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Main library of the 'overlays' extension.
+ *
+ * It aims to improve on the performance of the original overlaying mechanism provided by t3lib_page
+ * and to provide a more useful API for developers
+ *
+ * @author Francois Suter (Cobweb) <typo3@cobweb.ch>
+ * @package TYPO3
+ * @subpackage tx_overlays
+ */
+final class OverlayEngine {
+       static public $tableFields = array();
+
+       /**
+        * Gets all the records from a given table, properly overlaid with versions and translations.
+        *
+        * Its parameters are the same as t3lib_db::exec_SELECTquery().
+        * A small difference is that it will take only a single table.
+        * The big difference is that it returns an array of properly overlaid records and not a result pointer.
+        *
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @param string $fromTable Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $whereClause Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
+        * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
+        * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
+        * @param string $limit Optional LIMIT value ([begin,]max), if none, supply blank string.
+        * @param string $indexField Optional name of a field to use as an index for the result array. Must be included in the list of select fields.
+        * @return array Fully overlaid recordset
+        */
+       public static function getAllRecordsForTable($selectFields, $fromTable, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '', $indexField = '') {
+               // SQL WHERE clause is the base clause passed to the function
+               $where = $whereClause;
+               // Add language condition
+               $condition = self::getLanguageCondition($fromTable);
+               if (!empty($condition)) {
+                       if (!empty($where)) {
+                               $where .= ' AND ';
+                       }
+                       $where .= '(' . $condition . ')';
+               }
+               // Add enable fields condition
+               $condition = self::getEnableFieldsCondition($fromTable);
+               if (!empty($condition)) {
+                       if (!empty($where)) {
+                               $where .= ' AND ';
+                       }
+                       $where .= '(' . $condition . ')';
+               }
+               // Add workspace condition
+               $condition = self::getVersioningCondition($fromTable);
+               if (!empty($condition)) {
+                       if (!empty($where)) {
+                               $where .= ' AND ';
+                       }
+                       $where .= '(' . $condition . ')';
+               }
+
+               // If the language is not default, prepare for overlays
+               $doOverlays = FALSE;
+               if ($GLOBALS['TSFE']->sys_language_content > 0) {
+                       // Make sure the list of selected fields includes the necessary language fields
+                       // so that language overlays can be gotten properly
+                       try {
+                               $selectFields = self::selectOverlayFields($fromTable, $selectFields);
+                               $doOverlays = TRUE;
+                       } catch (\Exception $e) {
+                               // If the language fields could not be gotten, avoid overlay process
+                               $doOverlays = FALSE;
+                       }
+               }
+               // If versioning preview is on, prepare for version overlays
+               $doVersioning = FALSE;
+               if ($GLOBALS['TSFE']->sys_page->versioningPreview) {
+                       try {
+                               $selectFields = self::selectVersioningFields($fromTable, $selectFields);
+                               $doVersioning = TRUE;
+                       } catch (\Exception $e) {
+                               $doVersioning = FALSE;
+                       }
+               }
+
+               // Add base fields (uid, pid) if translations or versioning are activated
+               if ($doOverlays || $doVersioning) {
+                       try {
+                               $selectFields = self::selectBaseFields($fromTable, $selectFields);
+                       } catch (\Exception $e) {
+                               // Neither translations nor versioning can happen without uid and pid
+                               $doOverlays = FALSE;
+                               $doVersioning = FALSE;
+                       }
+               }
+
+               // Execute the query itself
+               $records = self::getDatabaseConnection()->exec_SELECTgetRows(
+                       $selectFields,
+                       $fromTable,
+                       $where,
+                       $groupBy,
+                       $orderBy,
+                       $limit,
+                       $indexField
+               );
+               // Perform version overlays, if needed
+               if ($doVersioning) {
+                       foreach ($records as $index => $aRecord) {
+                               $GLOBALS['TSFE']->sys_page->versionOL($fromTable, $aRecord);
+                                       // The versioned record may actually be FALSE if it is meant to be deleted
+                                       // in the workspace. To be really clean, unset it.
+                               if ($aRecord === FALSE) {
+                                       unset($records[$index]);
+                               }
+                       }
+               }
+
+               // If we have both a uid and a pid field, we can proceed with overlaying the records
+               if ($doOverlays) {
+                       $records = self::overlayRecordSet(
+                               $fromTable,
+                               $records,
+                               $GLOBALS['TSFE']->sys_language_content,
+                               $GLOBALS['TSFE']->sys_language_contentOL,
+                               $doVersioning
+                       );
+               }
+               return $records;
+       }
+
+       /**
+        * Retrieves a single record from the given table, properly overlaid for version and language.
+        *
+        * NOTE: this method first collects all records and then returns the first one, which makes it possible
+        * to filter out records which may not have a translation, for example. However this is not perfect as the
+        * sorting is still done on the SQL side, so that the first record in a translated language may not be correct
+        * for alphabetical ordering. A sorting on the PHP side could be included in the future, similar to what is
+        * done class tx_dataquery_wrapper (EXT:dataquery).
+        *
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @param string $fromTable Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $whereClause Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
+        * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
+        * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
+        * @return array
+        * @throws \Exception
+        */
+       public static function getSingleRecordForTable($selectFields, $fromTable, $whereClause = '', $groupBy = '', $orderBy = '') {
+               $records = self::getAllRecordsForTable($selectFields, $fromTable, $whereClause, $groupBy, $orderBy);
+               if (count($records) > 0) {
+                       return array_shift($records);
+               } else {
+                       throw new \Exception('No record found', 1397483854);
+               }
+       }
+
+       /**
+        * This method gets the SQL condition to apply for fetching the proper language
+        * depending on the localization settings in the TCA
+        *
+        * @param string $table True name of the table to assemble the condition for
+        * @param string $alias Alias to use for the table instead of its true name
+        * @return string SQL to add to the WHERE clause (without "AND")
+        */
+       public static function getLanguageCondition($table, $alias = '') {
+               $languageCondition = '';
+               if (empty($alias)) {
+                       $alias = $table;
+               }
+
+               // First check if there's actually a TCA for the given table
+               if (isset($GLOBALS['TCA'][$table]['ctrl'])) {
+                       $tableCtrlTCA = $GLOBALS['TCA'][$table]['ctrl'];
+
+                       // Assemble language condition only if a language field is defined
+                       if (!empty($tableCtrlTCA['languageField'])) {
+                               if (isset($GLOBALS['TSFE']->sys_language_contentOL) && isset($tableCtrlTCA['transOrigPointerField'])) {
+                                       // Default language and "all" language
+                                       $languageCondition = $alias . '.' . $tableCtrlTCA['languageField'] . ' IN (0,-1)';
+
+                                       // If current language is not default, select elements that exist only for current language
+                                       // That means elements that exist for current language but have no parent element
+                                       if ($GLOBALS['TSFE']->sys_language_content > 0) {
+                                               $languageCondition .= ' OR (' . $alias . '.' . $tableCtrlTCA['languageField'] . " = '" . $GLOBALS['TSFE']->sys_language_content . "' AND " . $alias . '.' . $tableCtrlTCA['transOrigPointerField'] . " = '0')";
+                                       }
+                               } else {
+                                       $languageCondition = $alias . '.' . $tableCtrlTCA['languageField'] . " = '" . $GLOBALS['TSFE']->sys_language_content . "'";
+                               }
+                       }
+               }
+               return $languageCondition;
+       }
+
+       /**
+        * Returns the condition on enable fields for the given table.
+        *
+        * Basically it calls on the method provided by \TYPO3\CMS\Frontend\Page\PageRepository, but without the " AND " in front.
+        *
+        * @param string $table Name of the table to build the condition for
+        * @param boolean $showHidden Set to TRUE to force the display of hidden records
+        * @param array $ignoreArray Use keys like "disabled", "starttime", "endtime", "fe_group" (i.e. keys from "enablefields" in TCA) and set values to TRUE to exclude corresponding conditions from WHERE clause
+        * @return string SQL to add to the WHERE clause (without "AND")
+        * @see \TYPO3\CMS\Frontend\Page\PageRepository::enableFields()
+        */
+       public static function getEnableFieldsCondition($table, $showHidden = FALSE, $ignoreArray = array()) {
+               try {
+                       $showHidden = $showHidden ? $showHidden : ($table == 'pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords);
+                       $enableCondition = $GLOBALS['TSFE']->sys_page->enableFields($table, $showHidden , $ignoreArray);
+                       // If an enable clause was returned, strip the first ' AND '
+                       if (!empty($enableCondition)) {
+                               $enableCondition = substr($enableCondition, strlen(' AND '));
+                       }
+               }
+               catch (\Exception $e) {
+                       $enableCondition = '';
+               }
+               return $enableCondition;
+       }
+
+       /**
+        * Assembles the proper condition with regards to versioning/workspaces.
+        *
+        * Explanations on parameter $getOverlaysDirectly:
+        * -----------------------------------------------
+        * The base condition assembled by this method will get the placeholders for new or modified records.
+        * This is normally the right way to do things, since those records are overlaid with their workspace version afterwards.
+        * However if you want this condition as part of a more complicated query implying JOINs,
+        * selecting placeholders will not work as the relationships are normally built with the version overlays
+        * and not the placeholders. In this case it is desirable to select the overlays directly,
+        * which can be achieved by setting $getOverlaysDirectly to TRUE
+        *
+        * NOTE: if this all sounds like gibberish, try reading more about workspaces in "Core API"
+        * (there's also quite some stuff in "Inside TYPO3", but part of it is badly outdated)
+        *
+        * @param string $table True name of the table to build the condition for
+        * @param string $alias Alias to use for the table instead of its true name
+        * @param boolean $getOverlaysDirectly Flag to choose original/placeholder records or overlays (see explanations above)
+        * @return string SQL to add to the WHERE clause (without "AND")
+        */
+       public static function getVersioningCondition($table, $alias = '', $getOverlaysDirectly = FALSE) {
+               $workspaceCondition = '';
+               if (empty($alias)) {
+                       $alias = $table;
+               }
+
+               // If the table has some TCA definition, check workspace handling
+               if (isset($GLOBALS['TCA'][$table]['ctrl']) && !empty($GLOBALS['TCA'][$table]['ctrl']['versioningWS'])) {
+
+                       // Base condition to get only live records
+                       // (they get overlaid afterwards in case of preview)
+                       $workspaceCondition .= '(' . $alias . '.t3ver_state <= 0 AND ' . $alias . '.t3ver_oid = 0)';
+
+                       // Additional conditions when previewing a workspace
+                       if ($GLOBALS['TSFE']->sys_page->versioningPreview) {
+                               $workspace = intval($GLOBALS['BE_USER']->workspace);
+                               // Condition for records that are unmodified but whose parent was modified
+                               // (when a parent record is modified, copies of its children are made that refer to the modified parent)
+                               $workspaceCondition .= ' OR (' . $alias . '.t3ver_state = 0 AND ' . $alias . '.t3ver_wsid = ' . $workspace . ')';
+                               // Choose the version state of records to select based on the $getOverlaysDirectly flag
+                               // (see explanations in the phpDoc comment above)
+                               $modificationPlaceholderState = 1;
+                               $movePlaceholderState = 3;
+                               if ($getOverlaysDirectly) {
+                                       $modificationPlaceholderState = -1;
+                                       $movePlaceholderState = 4;
+                               }
+                               // Select new records (which exist only in the workspace)
+                               // This is achieved by selecting the placeholders, which will be overlaid
+                               // with the actual content later when calling t3lib_page::versionOL()
+                               $workspaceCondition .= ' OR (' . $alias . '.t3ver_state = ' . $modificationPlaceholderState . ' AND ' . $alias . '.t3ver_wsid = ' . $workspace . ')';
+                               // Move-to placeholder
+                               $workspaceCondition .= ' OR (' . $alias . '.t3ver_state = ' . $movePlaceholderState . ' AND ' . $alias . '.t3ver_wsid = ' . $workspace . ')';
+                       }
+               }
+               return $workspaceCondition;
+       }
+
+       /**
+        * Gets all fields for a given table and stores that list into an internal cache array,
+        * then returns the list of fields.
+        *
+        * @param string $table Name of the table to fetch the fields for
+        * @return array List of fields for the given table
+        */
+       public static function getAllFieldsForTable($table) {
+               if (!isset(self::$tableFields[$table])) {
+                       self::$tableFields[$table] = self::getDatabaseConnection()->admin_get_fields($table);
+               }
+               return self::$tableFields[$table];
+       }
+
+       /**
+        * Makes sure that base fields such as uid and pid are included
+        * in the list of selected fields.
+        *
+        * These fields are absolutely necessary when
+        * translations or versioning overlays are being made.
+        * The method throws an \Exception if the fields are not available.
+        *
+        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @throws \Exception
+        * @return string The modified SELECT string
+        */
+       public static function selectBaseFields($table, $selectFields) {
+               $select = $selectFields;
+               // Don't bother if all fields are selected anyway
+               if ($selectFields != '*') {
+                       $hasUidField = FALSE;
+                       $hasPidField = FALSE;
+                       // Get the list of fields for the given table
+                       $tableFields = self::getAllFieldsForTable($table);
+
+                       // Add the fields, if available
+                       // NOTE: this may add the fields twice if they are already
+                       // in the list of selected fields, but that doesn't hurt
+                       // It doesn't seem worth making a very precise parsing of the list
+                       // of selected fields just to avoid duplicates
+                       if (isset($tableFields['uid'])) {
+                               $select .= ', ' . $table . '.uid';
+                               $hasUidField = TRUE;
+                       }
+                       if (isset($tableFields['pid'])) {
+                               $select .= ', ' . $table . '.pid';
+                               $hasPidField = TRUE;
+                       }
+                       // If one of the fields is still missing after that, throw an \Exception
+                       if ($hasUidField === FALSE || $hasPidField === FALSE) {
+                               throw new \Exception('Not all base fields are available.', 1284463019);
+                       }
+               }
+               return $select;
+       }
+
+       /**
+        * Makes sure that all the fields necessary for proper overlaying are included
+        * in the list of selected fields and exist in the table being queried.
+        *
+        * If not, it lets the \Exception thrown by tx_context::selectOverlayFieldsArray() bubble up.
+        *
+        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @return string Possibly modified list of fields to select
+        */
+       public static function selectOverlayFields($table, $selectFields) {
+               $additionalFields = self::selectOverlayFieldsArray($table, $selectFields);
+               if (count($additionalFields) > 0) {
+                       foreach ($additionalFields as $aField) {
+                               $selectFields .= ', ' . $table . '.' . $aField;
+                       }
+               }
+               return $selectFields;
+       }
+
+       /**
+        * Checks which fields need to be added to the given list of SELECTed fields
+        * so that language overlays can take place properly.
+        *
+        * If some information is missing, it throws an \Exception.
+        *
+        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @throws \Exception
+        * @return array List of fields to add
+        */
+       public static function selectOverlayFieldsArray($table, $selectFields) {
+               $additionalFields = array();
+
+               // If all fields are selected anyway, no need to worry
+               if ($selectFields != '*') {
+                       // Check if the table indeed has a TCA
+                       if (isset($GLOBALS['TCA'][$table]['ctrl'])) {
+
+                               // Continue only if table is not using foreign tables for translations
+                               // (in this case no additional field is needed) and has a language field
+                               if (empty($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']) && !empty($GLOBALS['TCA'][$table]['ctrl']['languageField'])) {
+                                       $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'];
+
+                                       // In order to be properly overlaid, a table has to have a given languageField
+                                       $hasLanguageField = strpos($selectFields, $languageField);
+                                       if ($hasLanguageField === FALSE) {
+                                               // Get the list of fields for the given table
+                                               $tableFields = self::getAllFieldsForTable($table);
+                                               if (isset($tableFields[$languageField])) {
+                                                       $additionalFields[] = $languageField;
+                                                       $hasLanguageField = TRUE;
+                                               }
+                                       }
+                                       // If language field is still missing after that, throw an \Exception
+                                       if ($hasLanguageField === FALSE) {
+                                               throw new \Exception('Language field not available.', 1284463837);
+                                       }
+                               }
+
+                       // The table has no TCA, throw an \Exception
+                       } else {
+                               throw new \Exception('No TCA for table, cannot add overlay fields.', 1284474025);
+                       }
+               }
+               return $additionalFields;
+       }
+
+       /**
+        * Makes sure that all the fields necessary for proper versioning overlays are included
+        * in the list of selected fields and exist in the table being queried.
+        *
+        * If not, it lets the \Exception thrown by tx_context::selectVersioningFieldsArray() bubble up.
+        *
+        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @return string Possibly modified list of fields to select
+        */
+       public static function selectVersioningFields($table, $selectFields) {
+               $additionalFields = self::selectVersioningFieldsArray($table, $selectFields);
+               if (count($additionalFields) > 0) {
+                       foreach ($additionalFields as $aField) {
+                               $selectFields .= ', ' . $table . '.' . $aField;
+                       }
+               }
+               return $selectFields;
+       }
+
+       /**
+        * Checks which fields need to be added to the given list of SELECTed fields
+        * so that versioning overlays can take place properly.
+        *
+        * If some information is missing, it throws an \Exception.
+        *
+        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
+        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+        * @throws \Exception
+        * @return array List of fields to add
+        */
+       public static function selectVersioningFieldsArray($table, $selectFields) {
+               $additionalFields = array();
+
+               // If all fields are selected anyway, no need to worry
+               if ($selectFields != '*') {
+                       // Check if the table indeed has a TCA and versioning information
+                       if (isset($GLOBALS['TCA'][$table]['ctrl']) && !empty($GLOBALS['TCA'][$table]['ctrl']['versioningWS'])) {
+
+                               // In order for versioning to work properly, the version state field is needed
+                               $stateField = 't3ver_state';
+                               $hasStateField = strpos($selectFields, $stateField);
+                               if ($hasStateField === FALSE) {
+                                       // Get the list of fields for the given table
+                                       $tableFields = self::getAllFieldsForTable($table);
+                                       if (isset($tableFields[$stateField])) {
+                                               $additionalFields[] = $stateField;
+                                               $hasStateField = TRUE;
+                                       }
+                               }
+                               // If state field is still missing after that, throw an \Exception
+                               if ($hasStateField === FALSE) {
+                                       throw new \Exception('Fields for versioning were not all available.', 1284473941);
+                               }
+
+                       // The table has no TCA, throw an \Exception
+                       } else {
+                               throw new \Exception('No TCA for table, cannot add versioning fields.', 1284474016);
+                       }
+               }
+               return $additionalFields;
+       }
+
+       /**
+        * Creates language-overlay for records in general (where translation is found in records from the same table).
+        *
+        * This is originally copied from \TYPO3\CMS\Frontend\Page\PageRepository::getRecordOverlay()
+        *
+        * @param string $table Table name
+        * @param array $recordset Full recordset to overlay. Must contain uid, pid and $TCA[$table]['ctrl']['languageField']
+        * @param integer $currentLanguage Uid of the currently selected language in the FE
+        * @param string $overlayMode Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but removed instead.
+        * @param boolean $doVersioning True if workspace preview is on
+        * @return array Returns the full overlaid recordset. If $overlayMode is "hideNonTranslated" then some records may be missing if no translation was found.
+        * @see \TYPO3\CMS\Frontend\Page\PageRepository::getRecordOverlay()
+        */
+       public static function overlayRecordSet($table, $recordset, $currentLanguage, $overlayMode = '', $doVersioning = FALSE) {
+
+               // Test with the first row if uid and pid fields are present
+               $firstRecord = current($recordset);
+               if ($firstRecord !== FALSE && !empty($firstRecord['uid']) && !empty($firstRecord['pid'])) {
+
+                       // Test if the table has a TCA definition
+                       if (isset($GLOBALS['TCA'][$table])) {
+                               $tableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
+
+                               // Test if the TCA definition includes translation information for the same table
+                               if (isset($tableCtrl['languageField']) && isset($tableCtrl['transOrigPointerField'])) {
+
+                                       // Test with the first row if languageField is present
+                                       if (isset($firstRecord[$tableCtrl['languageField']])) {
+
+                                               // Filter out records that are not in the default or [ALL] language, should there be any
+                                               $filteredRecordset = array();
+                                               foreach ($recordset as $index => $row) {
+                                                       if ($row[$tableCtrl['languageField']] <= 0) {
+                                                               $filteredRecordset[$index] = $row;
+                                                       }
+                                               }
+                                               // Will try to overlay a record only if the sys_language_content value is larger than zero,
+                                               // that is, it is not default or [ALL] language
+                                               if ($currentLanguage > 0) {
+                                                       // Assemble a list of uid's for getting the overlays,
+                                                       // but only from the filtered recordset
+                                                       $uidList = array();
+                                                       foreach ($filteredRecordset as $row) {
+                                                               $uidList[] = $row['uid'];
+                                                       }
+
+                                                       // Get all overlay records
+                                                       $overlays = self::getLocalOverlayRecords($table, $uidList, $currentLanguage, $doVersioning);
+
+                                                       // Now loop on the filtered recordset and try to overlay each record
+                                                       $overlaidRecordset = array();
+                                                       foreach ($recordset as $index => $row) {
+                                                               // If record is already in the right language, keep it as is
+                                                               if ($row[$tableCtrl['languageField']] == $currentLanguage) {
+                                                                       $overlaidRecordset[$index] = $row;
+
+                                                               // Else try to apply an overlay
+                                                               } elseif (isset($overlays[$row['uid']][$row['pid']])) {
+                                                                       $overlaidRecordset[$index] = self::overlaySingleRecord($table, $row, $overlays[$row['uid']][$row['pid']]);
+
+                                                               // No overlay exists, apply relevant translation rules
+                                                               } else {
+                                                                       // Take original record, only if non-translated are not hidden, or if language is [All]
+                                                                       if ($overlayMode != 'hideNonTranslated' || $row[$tableCtrl['languageField']] == -1) {
+                                                                               $overlaidRecordset[$index] = $row;
+                                                                       }
+                                                               }
+                                                       }
+                                                       // Return the overlaid recordset
+                                                       return $overlaidRecordset;
+
+                                               } else {
+                                                       // When default language is displayed, we never want to return a record carrying another language!
+                                                       // Return the filtered recordset
+                                                       return $filteredRecordset;
+                                               }
+
+                                       // Provided recordset does not contain languageField field, return recordset unchanged
+                                       } else {
+                                               return $recordset;
+                                       }
+
+                               // Test if the TCA definition includes translation information for a foreign table
+                               } elseif (isset($tableCtrl['transForeignTable'])) {
+                                       // The foreign table has a TCA structure. We can proceed.
+                                       if (isset($GLOBALS['TCA'][$tableCtrl['transForeignTable']])) {
+                                               $foreignCtrl = $GLOBALS['TCA'][$tableCtrl['transForeignTable']]['ctrl'];
+                                               // Check that the foreign table is indeed the appropriate translation table
+                                               // and also check that the foreign table has all the necessary TCA definitions
+                                               if (!empty($foreignCtrl['transOrigPointerTable']) && $foreignCtrl['transOrigPointerTable'] == $table && !empty($foreignCtrl['transOrigPointerField']) && !empty($foreignCtrl['languageField'])) {
+                                                       // Assemble a list of all uid's of records to translate
+                                                       $uidList = array();
+                                                       foreach ($recordset as $row) {
+                                                               $uidList[] = $row['uid'];
+                                                       }
+
+                                                       // Get all overlay records
+                                                       $overlays = self::getForeignOverlayRecords($tableCtrl['transForeignTable'], $uidList, $currentLanguage, $doVersioning);
+
+                                                       // Now loop on the filtered recordset and try to overlay each record
+                                                       $overlaidRecordset = array();
+                                                       foreach ($recordset as $index => $row) {
+                                                               // An overlay exists, apply it
+                                                               if (isset($overlays[$row['uid']])) {
+                                                                       $overlaidRecordset[$index] = self::overlaySingleRecord($table, $row, $overlays[$row['uid']]);
+
+                                                               // No overlay exists
+                                                               } else {
+                                                                       // Take original record, only if non-translated are not hidden
+                                                                       if ($overlayMode != 'hideNonTranslated') {
+                                                                               $overlaidRecordset[$index] = $row;
+                                                                       }
+                                                               }
+                                                       }
+                                                       // Return the overlaid recordset
+                                                       return $overlaidRecordset;
+
+                                       // The foreign table definition is incomplete, don't perform overlays and
+                                       // return recordset as is
+                                               } else {
+                                                       return $recordset;
+                                               }
+
+                                       // The foreign table has no TCA definition, it's impossible to perform overlays
+                                       // Return recordset as is
+                                       } else {
+                                               return $recordset;
+                                       }
+
+                               // No appropriate language fields defined in TCA, return recordset unchanged
+                               } else {
+                                       return $recordset;
+                               }
+
+                       // No TCA for table, return recordset unchanged
+                       } else {
+                               return $recordset;
+                       }
+               }
+               // Recordset did not contain uid or pid field, return recordset unchanged
+               else {
+                       return $recordset;
+               }
+       }
+
+       /**
+        * Wraps around getLocalOverlayRecords() and getForeignOverlayRecords().
+        *
+        * It makes it possible to use the same call whether translations are in the same table or
+        * in a foreign table. This method dispatches accordingly.
+        *
+        * @param string $table Name of the table for which to fetch the records
+        * @param array $uids Array of all uid's of the original records for which to fetch the translation
+        * @param integer $currentLanguage Uid of the system language to translate to
+        * @param boolean $doVersioning True if versioning overlay must be performed
+        * @return array All overlay records arranged per original uid and per pid, so that they can be checked (this is related to workspaces)
+        */
+       public static function getOverlayRecords($table, $uids, $currentLanguage, $doVersioning = FALSE) {
+               if (is_array($uids) && count($uids) > 0) {
+                       if (isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])) {
+                               return self::getForeignOverlayRecords($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'], $uids, $currentLanguage, $doVersioning);
+                       } else {
+                               return self::getLocalOverlayRecords($table, $uids, $currentLanguage, $doVersioning);
+                       }
+               } else {
+                       return array();
+               }
+       }
+
+       /**
+        * Retrieves all the records for overlaying other records
+        * when those records are stored in the same table as the originals.
+        *
+        * @param string $table Name of the table for which to fetch the records
+        * @param array $uids Array of all uid's of the original records for which to fetch the translation
+        * @param integer $currentLanguage Uid of the system language to translate to
+        * @param boolean $doVersioning True if versioning overlay must be performed
+        * @return array All overlay records arranged per original uid and per pid, so that they can be checked (this is related to workspaces)
+        */
+       public static function getLocalOverlayRecords($table, $uids, $currentLanguage, $doVersioning = FALSE) {
+               $overlays = array();
+               if (is_array($uids) && count($uids) > 0) {
+                       $tableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
+                       // Select overlays for all records
+                       $where = $tableCtrl['languageField'] . ' = ' . intval($currentLanguage) .
+                               ' AND ' . $tableCtrl['transOrigPointerField'] . ' IN (' . implode(', ', $uids) . ')';
+                       $enableCondition = self::getEnableFieldsCondition($table);
+                       if (!empty($enableCondition)) {
+                               $where .= ' AND ' . $enableCondition;
+                       }
+                       $rows = self::getDatabaseConnection()->exec_SELECTgetRows(
+                               '*',
+                               $table,
+                               $where
+                       );
+                       // Arrange overlay records according to transOrigPointerField, so that it's easy to relate them to the originals
+                       // This structure is actually a 2-dimensional array, with the pid as the second key
+                       // Because of versioning, there may be several overlays for a given original and matching the pid too
+                       // ensures that we are referring to the correct overlay
+                       foreach ($rows as $row) {
+                               // Perform version overlays, if needed
+                               if ($doVersioning) {
+                                       $GLOBALS['TSFE']->sys_page->versionOL($table, $row);
+                               }
+                               // The versioned record may actually be FALSE if it is meant to be deleted
+                               // in the workspace. To be really clean, unset it.
+                               if ($row !== FALSE) {
+                                       if (!isset($overlays[$row[$tableCtrl['transOrigPointerField']]])) {
+                                               $overlays[$row[$tableCtrl['transOrigPointerField']]] = array();
+                                       }
+                                       $overlays[$row[$tableCtrl['transOrigPointerField']]][$row['pid']] = $row;
+                               }
+                       }
+               }
+               return $overlays;
+       }
+
+       /**
+        * This method is used to retrieve all the records for overlaying other records
+        * when those records are stored in a different table than the originals
+        *
+        * @param string $table Name of the table for which to fetch the records
+        * @param array $uids Array of all uid's of the original records for which to fetch the translation
+        * @param integer $currentLanguage Uid of the system language to translate to
+        * @param boolean $doVersioning True if versioning overlay must be performed
+        * @return array All overlay records arranged per original uid and per pid, so that they can be checked (this is related to workspaces)
+        */
+       public static function getForeignOverlayRecords($table, $uids, $currentLanguage, $doVersioning = FALSE) {
+               $overlays = array();
+               if (is_array($uids) && count($uids) > 0) {
+                       $tableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
+                       // Select overlays for all records
+                       $where = $tableCtrl['languageField'] . ' = ' . intval($currentLanguage) .
+                               ' AND ' . $tableCtrl['transOrigPointerField'] . ' IN (' . implode(', ', $uids) . ')';
+                       $enableCondition = self::getEnableFieldsCondition($table);
+                       if (!empty($enableCondition)) {
+                               $where .= ' AND ' . $enableCondition;
+                       }
+                       $rows = self::getDatabaseConnection()->exec_SELECTgetRows(
+                               '*',
+                               $table,
+                               $where
+                       );
+                       // Arrange overlay records according to transOrigPointerField, so that it's easy to relate them to the originals
+                       foreach ($rows as $row) {
+                               // Perform version overlays, if needed
+                               if ($doVersioning) {
+                                       $GLOBALS['TSFE']->sys_page->versionOL($table, $row);
+                               }
+                               // The versioned record may actually be FALSE if it is meant to be deleted
+                               // in the workspace. To be really clean, unset it.
+                               if ($row !== FALSE) {
+                                       $overlays[$row[$tableCtrl['transOrigPointerField']]] = $row;
+                               }
+                       }
+               }
+               return $overlays;
+       }
+
+       /**
+        * Takes a record and its overlay and performs the overlay according to active translation rules.
+        *
+        * This piece of code is extracted from \TYPO3\CMS\Frontend\Page\PageRepository::getRecordOverlay().
+        *
+        * @param string $table Name of the table for which the operation is taking place
+        * @param array $record Record to overlay
+        * @param array $overlay Overlay of the record
+        * @return array Overlaid record
+        * @see \TYPO3\CMS\Frontend\Page\PageRepository::getRecordOverlay()
+        */
+       public static function overlaySingleRecord($table, $record, $overlay) {
+               $overlaidRecord = $record;
+               $overlaidRecord['_LOCALIZED_UID'] = $overlay['uid'];
+               foreach ($record as $key => $value) {
+                       if ($key != 'uid' && $key != 'pid' && isset($overlay[$key])) {
+                               $l10mMode = self::getL10nModeForColumn($table, $key);
+                               if (empty($l10mMode)) {
+                                       $overlaidRecord[$key] = $overlay[$key];
+                               } else {
+                                       if ($l10mMode != 'exclude' && ($l10mMode != 'mergeIfNotBlank' || strcmp(trim($overlay[$key]), ''))) {
+                                               $overlaidRecord[$key] = $overlay[$key];
+                                       }
+                               }
+                       }
+               }
+               return $overlaidRecord;
+       }
+
+       /**
+        * Gets the l10n_mode value.
+        *
+        * @param string $table Name of the table being looked up
+        * @param string $column Name of the column being looked up
+        * @return string Value of the l10n_mode property, a blank string if undefined
+        */
+       public static function getL10nModeForColumn($table, $column) {
+               return (isset($GLOBALS['TCA'][$table]['columns'][$column]['l10n_mode'])) ? $GLOBALS['TCA'][$table]['columns'][$column]['l10n_mode'] : '';
+       }
+
+       /**
+        * Returns the global database object.
+        *
+        * @return \TYPO3\CMS\Core\Database\DatabaseConnection
+        */
+       protected static function getDatabaseConnection() {
+               return $GLOBALS['TYPO3_DB'];
+       }
+}
diff --git a/class.tx_overlays.php b/class.tx_overlays.php
deleted file mode 100644 (file)
index 116ee78..0000000
+++ /dev/null
@@ -1,776 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2008-2012 Francois Suter (Cobweb) <typo3@cobweb.ch>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-
-/**
- * Main library of the 'overlays' extension.
- * It aims to improve on the performance of the original overlaying mechanism provided by t3lib_page
- * and to provide a more useful API for developers
- *
- * @author             Francois Suter (Cobweb) <typo3@cobweb.ch>
- * @package            TYPO3
- * @subpackage tx_overlays
- *
- * $Id$
- */
-final class tx_overlays {
-       static public $tableFields = array();
-
-       /**
-        * This method is designed to get all the records from a given table, properly overlaid with versions and translations
-        * Its parameters are the same as t3lib_db::exec_SELECTquery()
-        * A small difference is that it will take only a single table
-        * The big difference is that it returns an array of properly overlaid records and not a result pointer
-        *
-        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @param string $fromTable Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param string $whereClause Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
-        * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
-        * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
-        * @param string $limit Optional LIMIT value ([begin,]max), if none, supply blank string.
-        * @param string $indexField Optional name of a field to use as an index for the result array. Must be included in the list of select fields.
-        * @return array Fully overlaid recordset
-        */
-       public static function getAllRecordsForTable($selectFields, $fromTable, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '', $indexField = '') {
-                       // SQL WHERE clause is the base clause passed to the function
-               $where = $whereClause;
-                       // Add language condition
-               $condition = self::getLanguageCondition($fromTable);
-               if (!empty($condition)) {
-                       if (!empty($where)) {
-                               $where .= ' AND ';
-                       }
-                       $where .= '(' . $condition . ')';
-               }
-                       // Add enable fields condition
-               $condition = self::getEnableFieldsCondition($fromTable);
-               if (!empty($condition)) {
-                       if (!empty($where)) {
-                               $where .= ' AND ';
-                       }
-                       $where .= '(' . $condition . ')';
-               }
-                       // Add workspace condition
-               $condition = self::getVersioningCondition($fromTable);
-               if (!empty($condition)) {
-                       if (!empty($where)) {
-                               $where .= ' AND ';
-                       }
-                       $where .= '(' . $condition . ')';
-               }
-
-                       // If the language is not default, prepare for overlays
-               $doOverlays = FALSE;
-               if ($GLOBALS['TSFE']->sys_language_content > 0) {
-                               // Make sure the list of selected fields includes the necessary language fields
-                               // so that language overlays can be gotten properly
-                       try {
-                               $selectFields = self::selectOverlayFields($fromTable, $selectFields);
-                               $doOverlays = TRUE;
-                       } catch (Exception $e) {
-                                       // If the language fields could not be gotten, avoid overlay process
-                               $doOverlays = FALSE;
-                       }
-               }
-                       // If versioning preview is on, prepare for version overlays
-               $doVersioning = FALSE;
-               if ($GLOBALS['TSFE']->sys_page->versioningPreview) {
-                       try {
-                               $selectFields = self::selectVersioningFields($fromTable, $selectFields);
-                               $doVersioning = TRUE;
-                       } catch (Exception $e) {
-                               $doVersioning = FALSE;
-                       }
-               }
-
-                       // Add base fields (uid, pid) if translations or versioning are activated
-               if ($doOverlays || $doVersioning) {
-                       try {
-                               $selectFields = self::selectBaseFields($fromTable, $selectFields);
-                       } catch (Exception $e) {
-                                       // Neither translations nor versioning can happen without uid and pid
-                               $doOverlays = FALSE;
-                               $doVersioning = FALSE;
-                       }
-               }
-
-                       // Execute the query itself
-               $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows($selectFields, $fromTable, $where, $groupBy, $orderBy, $limit, $indexField);
-                       // Perform version overlays, if needed
-               if ($doVersioning) {
-                       foreach ($records as $index => $aRecord) {
-                               $GLOBALS['TSFE']->sys_page->versionOL($fromTable, $aRecord);
-                                       // The versioned record may actually be FALSE if it is meant to be deleted
-                                       // in the workspace. To be really clean, unset it.
-                               if ($aRecord === FALSE) {
-                                       unset($records[$index]);
-                               }
-                       }
-               }
-
-                       // If we have both a uid and a pid field, we can proceed with overlaying the records
-               if ($doOverlays) {
-                       $records = self::overlayRecordSet($fromTable, $records, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL, $doVersioning);
-               }
-               return $records;
-       }
-
-       /**
-        * Retrieves a single record from the given table, properly overlaid for version and language.
-        *
-        * NOTE: this method first collects all records and then returns the first one, which makes it possible
-        * to filter out records which may not have a translation, for example. However this is not perfect as the
-        * sorting is still done on the SQL side, so that the first record in a translated language may not be correct
-        * for alphabetical ordering. A sorting on the PHP side could be included in the future, similar to what is
-        * done class tx_dataquery_wrapper (EXT:dataquery).
-        *
-        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @param string $fromTable Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param string $whereClause Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
-        * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
-        * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
-        * @return array
-        * @throws Exception
-        */
-       public static function getSingleRecordForTable($selectFields, $fromTable, $whereClause = '', $groupBy = '', $orderBy = '') {
-               $records = self::getAllRecordsForTable($selectFields, $fromTable, $whereClause, $groupBy, $orderBy);
-               if (count($records) > 0) {
-                       return array_shift($records);
-               } else {
-                       throw new \Exception('No record found', 1397483854);
-               }
-       }
-
-       /**
-        * This method gets the SQL condition to apply for fetching the proper language
-        * depending on the localization settings in the TCA
-        *
-        * @param       string          $table: (true) name of the table to assemble the condition for
-        * @param       string          $alias: alias to use for the table instead of its true name
-        * @return      string          SQL to add to the WHERE clause (without "AND")
-        */
-       public static function getLanguageCondition($table, $alias = '') {
-               $languageCondition = '';
-               if (empty($alias)) {
-                       $alias = $table;
-               }
-
-                       // First check if there's actually a TCA for the given table
-               if (isset($GLOBALS['TCA'][$table]['ctrl'])) {
-                       $tableCtrlTCA = $GLOBALS['TCA'][$table]['ctrl'];
-
-                               // Assemble language condition only if a language field is defined
-                       if (!empty($tableCtrlTCA['languageField'])) {
-                               if (isset($GLOBALS['TSFE']->sys_language_contentOL) && isset($tableCtrlTCA['transOrigPointerField'])) {
-                                               // Default language and "all" language
-                                       $languageCondition = $alias . '.' . $tableCtrlTCA['languageField'] . ' IN (0,-1)';
-
-                                               // If current language is not default, select elements that exist only for current language
-                                               // That means elements that exist for current language but have no parent element
-                                       if ($GLOBALS['TSFE']->sys_language_content > 0) {
-                                               $languageCondition .= ' OR (' . $alias . '.' . $tableCtrlTCA['languageField'] . " = '" . $GLOBALS['TSFE']->sys_language_content . "' AND " . $alias . '.' . $tableCtrlTCA['transOrigPointerField'] . " = '0')";
-                                       }
-                               } else {
-                                       $languageCondition = $alias . '.' . $tableCtrlTCA['languageField'] . " = '" . $GLOBALS['TSFE']->sys_language_content . "'";
-                               }
-                       }
-               }
-               return $languageCondition;
-       }
-
-       /**
-        * This method returns the condition on enable fields for the given table
-        * Basically it calls on the method provided by t3lib_page, but without the " AND " in front
-        *
-        * @param       string          $table: name of the table to build the condition for
-        * @param       boolean         $showHidden: set to TRUE to force the display of hidden records
-        * @param       array           $ignoreArray: use keys like "disabled", "starttime", "endtime", "fe_group" (i.e. keys from "enablefields" in TCA) and set values to TRUE to exclude corresponding conditions from WHERE clause
-        * @return      string          SQL to add to the WHERE clause (without "AND")
-        */
-       public static function getEnableFieldsCondition($table, $showHidden = FALSE, $ignoreArray = array()) {
-               $enableCondition = '';
-                       // First check if table has a TCA ctrl section, otherwise t3lib_page::enableFields() will die() (stupid thing!)
-                       // NOTE: since TYPO3 4.5, an exception is thrown, so this method could eventually be adapted
-               if (isset($GLOBALS['TCA'][$table]['ctrl'])) {
-                       $showHidden = $showHidden ? $showHidden : ($table == 'pages' ? $GLOBALS['TSFE']->showHiddenPage : $GLOBALS['TSFE']->showHiddenRecords);
-                       $enableCondition = $GLOBALS['TSFE']->sys_page->enableFields($table, $showHidden , $ignoreArray);
-                               // If an enable clause was returned, strip the first ' AND '
-                       if (!empty($enableCondition)) {
-                               $enableCondition = substr($enableCondition, strlen(' AND '));
-                       }
-               }
-                       // TODO: throw an exception if the given table has no TCA? (t3lib_page::enableFields() used a die)
-               return $enableCondition;
-       }
-
-       /**
-        * This method is used to assemble the proper condition with regards to versioning/workspaces
-        * However it is now deprecated and getVersioningCondition should be used instead
-        *
-        * @param array $table Name of the table to get the condition for
-        * @return string The SQL condition
-        * @deprecated Use self::getVersioningCondition() instead. Kept for backwards-compatibility but may be removed in the future.
-        */
-       public static function getWorkspaceCondition($table) {
-               t3lib_div::logDeprecatedFunction();
-               return self::getVersioningCondition($table);
-       }
-
-       /**
-        * This method assembles the proper condition with regards to versioning/workspaces
-        *
-        * Explanations on parameter $getOverlaysDirectly:
-        * -----------------------------------------------
-        * The base condition assembled by this method will get the placeholders for new or modified records.
-        * This is normally the right way to do things, since those records are overlaid with their workspace version afterwards.
-        * However if you want this condition as part of a more complicated query implying JOINs,
-        * selecting placeholders will not work as the relationships are normally built with the version overlays
-        * and not the placeholders. In this case it is desirable to select the overlays directly,
-        * which can be achieved by setting $getOverlaysDirectly to TRUE
-        *
-        * NOTE: if this all sounds like gibberish, try reading more about workspaces in "Core API"
-        * (there's also quite some stuff in "Inside TYPO3", but part of it is badly outdated)
-        *
-        * @param       string          $table: (true) name of the table to build the condition for
-        * @param       string          $alias: alias to use for the table instead of its true name
-        * @param       boolean         $getOverlaysDirectly: flag to choose original/placeholder records or overlays (see explanations above)
-        * @return      string          SQL to add to the WHERE clause (without "AND")
-        */
-       public static function getVersioningCondition($table, $alias = '', $getOverlaysDirectly = FALSE) {
-               $workspaceCondition = '';
-               if (empty($alias)) {
-                       $alias = $table;
-               }
-
-                       // If the table has some TCA definition, check workspace handling
-               if (isset($GLOBALS['TCA'][$table]['ctrl']) && !empty($GLOBALS['TCA'][$table]['ctrl']['versioningWS'])) {
-
-                               // Base condition to get only live records
-                               // (they get overlaid afterwards in case of preview)
-                       $workspaceCondition .= '(' . $alias . '.t3ver_state <= 0 AND ' . $alias . '.t3ver_oid = 0)';
-
-                               // Additional conditions when previewing a workspace
-                       if ($GLOBALS['TSFE']->sys_page->versioningPreview) {
-                               $workspace = intval($GLOBALS['BE_USER']->workspace);
-                                       // Condition for records that are unmodified but whose parent was modified
-                                       // (when a parent record is modified, copies of its children are made that refer to the modified parent)
-                               $workspaceCondition .= ' OR (' . $alias . '.t3ver_state = 0 AND ' . $alias . '.t3ver_wsid = ' . $workspace . ')';
-                                       // Choose the version state of records to select based on the $getOverlaysDirectly flag
-                                       // (see explanations in the phpDoc comment above)
-                               $modificationPlaceholderState = 1;
-                               $movePlaceholderState = 3;
-                               if ($getOverlaysDirectly) {
-                                       $modificationPlaceholderState = -1;
-                                       $movePlaceholderState = 4;
-                               }
-                                       // Select new records (which exist only in the workspace)
-                                       // This is achieved by selecting the placeholders, which will be overlaid
-                                       // with the actual content later when calling t3lib_page::versionOL()
-                               $workspaceCondition .= ' OR (' . $alias . '.t3ver_state = ' . $modificationPlaceholderState . ' AND ' . $alias . '.t3ver_wsid = ' . $workspace . ')';
-                                       // Move-to placeholder
-                               $workspaceCondition .= ' OR (' . $alias . '.t3ver_state = ' . $movePlaceholderState . ' AND ' . $alias . '.t3ver_wsid = ' . $workspace . ')';
-                       }
-               }
-               return $workspaceCondition;
-       }
-
-       /**
-        * This method gets all fields for a given table and stores that list
-        * into an internal cache array
-        * It then returns the list of fields
-        *
-        * @param       string  $table: name of the table to fetch the fields for
-        * @return      array   List of fields for the given table
-        */
-       public static function getAllFieldsForTable($table) {
-               if (!isset(self::$tableFields[$table])) {
-                       self::$tableFields[$table] = $GLOBALS['TYPO3_DB']->admin_get_fields($table);
-               }
-               return self::$tableFields[$table];
-       }
-
-       /**
-        * This method makes sure that base fields such as uid and pid are included
-        * in the list of selected fields. These fields are absolutely necessary when
-        * translations or versioning overlays are being made.
-        * The method throws an exception if the fields are not available.
-        *
-        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @throws Exception
-        * @return string The modified SELECT string
-        */
-       public static function selectBaseFields($table, $selectFields) {
-               $select = $selectFields;
-                       // Don't bother if all fields are selected anyway
-               if ($selectFields != '*') {
-                       $hasUidField = FALSE;
-                       $hasPidField = FALSE;
-                               // Get the list of fields for the given table
-                       $tableFields = self::getAllFieldsForTable($table);
-
-                               // Add the fields, if available
-                               // NOTE: this may add the fields twice if they are already
-                               // in the list of selected fields, but that doesn't hurt
-                               // It doesn't seem worth making a very precise parsing of the list
-                               // of selected fields just to avoid duplicates
-                       if (isset($tableFields['uid'])) {
-                               $select .= ', ' . $table . '.uid';
-                               $hasUidField = TRUE;
-                       }
-                       if (isset($tableFields['pid'])) {
-                               $select .= ', ' . $table . '.pid';
-                               $hasPidField = TRUE;
-                       }
-                               // If one of the fields is still missing after that, throw an exception
-                       if ($hasUidField === FALSE || $hasPidField === FALSE) {
-                               throw new Exception('Not all base fields are available.', 1284463019);
-                       }
-               }
-               return $select;
-       }
-
-       /**
-        * This method makes sure that all the fields necessary for proper overlaying are included
-        * in the list of selected fields and exist in the table being queried
-        * If not, it lets the exception thrown by tx_context::selectOverlayFieldsArray() bubble up
-        *
-        * @param       string          $table: Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param       string          $selectFields: List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @return      string          Possibly modified list of fields to select
-        */
-       public static function selectOverlayFields($table, $selectFields) {
-               $additionalFields = self::selectOverlayFieldsArray($table, $selectFields);
-               if (count($additionalFields) > 0) {
-                       foreach ($additionalFields as $aField) {
-                               $selectFields .= ', ' . $table . '.' . $aField;
-                       }
-               }
-               return $selectFields;
-       }
-
-       /**
-        * This method checks which fields need to be added to the given list of SELECTed fields
-        * so that language overlays can take place properly
-        * If some information is missing, it throws an exception
-        *
-        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @throws Exception
-        * @return array List of fields to add
-        */
-       public static function selectOverlayFieldsArray($table, $selectFields) {
-               $additionalFields = array();
-
-                       // If all fields are selected anyway, no need to worry
-               if ($selectFields != '*') {
-                               // Check if the table indeed has a TCA
-                       if (isset($GLOBALS['TCA'][$table]['ctrl'])) {
-
-                                       // Continue only if table is not using foreign tables for translations
-                                       // (in this case no additional field is needed) and has a language field
-                               if (empty($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']) && !empty($GLOBALS['TCA'][$table]['ctrl']['languageField'])) {
-                                       $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'];
-
-                                               // In order to be properly overlaid, a table has to have a given languageField
-                                       $hasLanguageField = strpos($selectFields, $languageField);
-                                       if ($hasLanguageField === FALSE) {
-                                                       // Get the list of fields for the given table
-                                               $tableFields = self::getAllFieldsForTable($table);
-                                               if (isset($tableFields[$languageField])) {
-                                                       $additionalFields[] = $languageField;
-                                                       $hasLanguageField = TRUE;
-                                               }
-                                       }
-                                               // If language field is still missing after that, throw an exception
-                                       if ($hasLanguageField === FALSE) {
-                                               throw new Exception('Language field not available.', 1284463837);
-                                       }
-                               }
-
-                               // The table has no TCA, throw an exception
-                       } else {
-                               throw new Exception('No TCA for table, cannot add overlay fields.', 1284474025);
-                       }
-               }
-               return $additionalFields;
-       }
-
-       /**
-        * This method makes sure that all the fields necessary for proper versioning overlays are included
-        * in the list of selected fields and exist in the table being queried
-        * If not, it lets the exception thrown by tx_context::selectVersioningFieldsArray() bubble up
-        *
-        * @param       string          $table: Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param       string          $selectFields: List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @return      string          Possibly modified list of fields to select
-        */
-       public static function selectVersioningFields($table, $selectFields) {
-               $additionalFields = self::selectVersioningFieldsArray($table, $selectFields);
-               if (count($additionalFields) > 0) {
-                       foreach ($additionalFields as $aField) {
-                               $selectFields .= ', ' . $table . '.' . $aField;
-                       }
-               }
-               return $selectFields;
-       }
-
-       /**
-        * This method checks which fields need to be added to the given list of SELECTed fields
-        * so that versioning overlays can take place properly
-        * If some information is missing, it throws an exception
-        *
-        * @param string $table Table from which to select. This is what comes right after "FROM ...". Required value.
-        * @param string $selectFields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-        * @throws Exception
-        * @return array List of fields to add
-        */
-       public static function selectVersioningFieldsArray($table, $selectFields) {
-               $additionalFields = array();
-
-                       // If all fields are selected anyway, no need to worry
-               if ($selectFields != '*') {
-                               // Check if the table indeed has a TCA and versioning information
-                       if (isset($GLOBALS['TCA'][$table]['ctrl']) && !empty($GLOBALS['TCA'][$table]['ctrl']['versioningWS'])) {
-
-                                       // In order for versioning to work properly, the version state field is needed
-                               $stateField = 't3ver_state';
-                               $hasStateField = strpos($selectFields, $stateField);
-                               if ($hasStateField === FALSE) {
-                                               // Get the list of fields for the given table
-                                       $tableFields = self::getAllFieldsForTable($table);
-                                       if (isset($tableFields[$stateField])) {
-                                               $additionalFields[] = $stateField;
-                                               $hasStateField = TRUE;
-                                       }
-                               }
-                                       // If state field is still missing after that, throw an exception
-                               if ($hasStateField === FALSE) {
-                                       throw new Exception('Fields for versioning were not all available.', 1284473941);
-                               }
-
-                               // The table has no TCA, throw an exception
-                       } else {
-                               throw new Exception('No TCA for table, cannot add versioning fields.', 1284474016);
-                       }
-               }
-               return $additionalFields;
-       }
-
-       /**
-        * Creates language-overlay for records in general (where translation is found in records from the same table)
-        * This is originally copied from t3lib_page::getRecordOverlay()
-        *
-        * @param       string          $table: Table name
-        * @param       array           $recordset: Full recordset to overlay. Must contain uid, pid and $TCA[$table]['ctrl']['languageField']
-        * @param       integer         $currentLanguage: Uid of the currently selected language in the FE
-        * @param       string          $overlayMode: Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but removed instead.
-        * @param       boolean         $doVersioning: true if workspace preview is on
-        * @return      array           Returns the full overlaid recordset. If $overlayMode is "hideNonTranslated" then some records may be missing if no translation was found.
-        */
-       public static function overlayRecordSet($table, $recordset, $currentLanguage, $overlayMode = '', $doVersioning = FALSE) {
-
-                       // Test with the first row if uid and pid fields are present
-               $firstRecord = current($recordset);
-               if ($firstRecord !== FALSE && !empty($firstRecord['uid']) && !empty($firstRecord['pid'])) {
-
-                               // Test if the table has a TCA definition
-                       if (isset($GLOBALS['TCA'][$table])) {
-                               $tableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
-
-                                       // Test if the TCA definition includes translation information for the same table
-                               if (isset($tableCtrl['languageField']) && isset($tableCtrl['transOrigPointerField'])) {
-
-                                               // Test with the first row if languageField is present
-                                       if (isset($firstRecord[$tableCtrl['languageField']])) {
-
-                                                       // Filter out records that are not in the default or [ALL] language, should there be any
-                                               $filteredRecordset = array();
-                                               foreach ($recordset as $index => $row) {
-                                                       if ($row[$tableCtrl['languageField']] <= 0) {
-                                                               $filteredRecordset[$index] = $row;
-                                                       }
-                                               }
-                                                       // Will try to overlay a record only if the sys_language_content value is larger than zero,
-                                                       // that is, it is not default or [ALL] language
-                                               if ($currentLanguage > 0) {
-                                                               // Assemble a list of uid's for getting the overlays,
-                                                               // but only from the filtered recordset
-                                                       $uidList = array();
-                                                       foreach ($filteredRecordset as $row) {
-                                                               $uidList[] = $row['uid'];
-                                                       }
-
-                                                               // Get all overlay records
-                                                       $overlays = self::getLocalOverlayRecords($table, $uidList, $currentLanguage, $doVersioning);
-
-                                                               // Now loop on the filtered recordset and try to overlay each record
-                                                       $overlaidRecordset = array();
-                                                       foreach ($recordset as $index => $row) {
-                                                                       // If record is already in the right language, keep it as is
-                                                               if ($row[$tableCtrl['languageField']] == $currentLanguage) {
-                                                                       $overlaidRecordset[$index] = $row;
-
-                                                                       // Else try to apply an overlay
-                                                               } elseif (isset($overlays[$row['uid']][$row['pid']])) {
-                                                                       $overlaidRecordset[$index] = self::overlaySingleRecord($table, $row, $overlays[$row['uid']][$row['pid']]);
-
-                                                                       // No overlay exists, apply relevant translation rules
-                                                               } else {
-                                                                               // Take original record, only if non-translated are not hidden, or if language is [All]
-                                                                       if ($overlayMode != 'hideNonTranslated' || $row[$tableCtrl['languageField']] == -1) {
-                                                                               $overlaidRecordset[$index] = $row;
-                                                                       }
-                                                               }
-                                                       }
-                                                               // Return the overlaid recordset
-                                                       return $overlaidRecordset;
-
-                                               } else {
-                                                               // When default language is displayed, we never want to return a record carrying another language!
-                                                               // Return the filtered recordset
-                                                       return $filteredRecordset;
-                                               }
-
-                                               // Provided recordset does not contain languageField field, return recordset unchanged
-                                       } else {
-                                               return $recordset;
-                                       }
-
-                                       // Test if the TCA definition includes translation information for a foreign table
-                               } elseif (isset($tableCtrl['transForeignTable'])) {
-                                               // The foreign table has a TCA structure. We can proceed.
-                                       if (isset($GLOBALS['TCA'][$tableCtrl['transForeignTable']])) {
-                                               $foreignCtrl = $GLOBALS['TCA'][$tableCtrl['transForeignTable']]['ctrl'];
-                                                       // Check that the foreign table is indeed the appropriate translation table
-                                                       // and also check that the foreign table has all the necessary TCA definitions
-                                               if (!empty($foreignCtrl['transOrigPointerTable']) && $foreignCtrl['transOrigPointerTable'] == $table && !empty($foreignCtrl['transOrigPointerField']) && !empty($foreignCtrl['languageField'])) {
-                                                               // Assemble a list of all uid's of records to translate
-                                                       $uidList = array();
-                                                       foreach ($recordset as $row) {
-                                                               $uidList[] = $row['uid'];
-                                                       }
-
-                                                               // Get all overlay records
-                                                       $overlays = self::getForeignOverlayRecords($tableCtrl['transForeignTable'], $uidList, $currentLanguage, $doVersioning);
-
-                                                               // Now loop on the filtered recordset and try to overlay each record
-                                                       $overlaidRecordset = array();
-                                                       foreach ($recordset as $index => $row) {
-                                                                       // An overlay exists, apply it
-                                                               if (isset($overlays[$row['uid']])) {
-                                                                       $overlaidRecordset[$index] = self::overlaySingleRecord($table, $row, $overlays[$row['uid']]);
-
-                                                                       // No overlay exists
-                                                               } else {
-                                                                               // Take original record, only if non-translated are not hidden
-                                                                       if ($overlayMode != 'hideNonTranslated') {
-                                                                               $overlaidRecordset[$index] = $row;
-                                                                       }
-                                                               }
-                                                       }
-                                                               // Return the overlaid recordset
-                                                       return $overlaidRecordset;
-
-                                               // The foreign table definition is incomplete, don't perform overlays and
-                                               // return recordset as is
-                                               } else {
-                                                       return $recordset;
-                                               }
-
-                                               // The foreign table has no TCA definition, it's impossible to perform overlays
-                                               // Return recordset as is
-                                       } else {
-                                               return $recordset;
-                                       }
-
-                                       // No appropriate language fields defined in TCA, return recordset unchanged
-                               } else {
-                                       return $recordset;
-                               }
-
-                               // No TCA for table, return recordset unchanged
-                       } else {
-                               return $recordset;
-                       }
-               }
-                       // Recordset did not contain uid or pid field, return recordset unchanged
-               else {
-                       return $recordset;
-               }
-       }
-
-       /**
-        * This method is a wrapper around getLocalOverlayRecords() and getForeignOverlayRecords().
-        * It makes it possible to use the same call whether translations are in the same table or
-        * in a foreign table. This method dispatches accordingly.
-        *
-        * @param       string          $table: name of the table for which to fetch the records
-        * @param       array           $uids: array of all uid's of the original records for which to fetch the translation
-        * @param       integer         $currentLanguage: uid of the system language to translate to
-        * @param       boolean         $doVersioning: true if versioning overlay must be performed
-        * @return      array           All overlay records arranged per original uid and per pid, so that they can be checked (this is related to workspaces)
-        */
-       public static function getOverlayRecords($table, $uids, $currentLanguage, $doVersioning = FALSE) {
-               if (is_array($uids) && count($uids) > 0) {
-                       if (isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])) {
-                               return self::getForeignOverlayRecords($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'], $uids, $currentLanguage, $doVersioning);
-                       } else {
-                               return self::getLocalOverlayRecords($table, $uids, $currentLanguage, $doVersioning);
-                       }
-               } else {
-                       return array();
-               }
-       }
-
-       /**
-        * This method is used to retrieve all the records for overlaying other records
-        * when those records are stored in the same table as the originals
-        *
-        * @param       string          $table: name of the table for which to fetch the records
-        * @param       array           $uids: array of all uid's of the original records for which to fetch the translation
-        * @param       integer         $currentLanguage: uid of the system language to translate to
-        * @param       boolean         $doVersioning: true if versioning overlay must be performed
-        * @return      array           All overlay records arranged per original uid and per pid, so that they can be checked (this is related to workspaces)
-        */
-       public static function getLocalOverlayRecords($table, $uids, $currentLanguage, $doVersioning = FALSE) {
-               $overlays = array();
-               if (is_array($uids) && count($uids) > 0) {
-                       $tableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
-                               // Select overlays for all records
-                       $where = $tableCtrl['languageField'] . ' = ' . intval($currentLanguage) .
-                               ' AND ' . $tableCtrl['transOrigPointerField'] . ' IN (' . implode(', ', $uids) . ')';
-                       $enableCondition = self::getEnableFieldsCondition($table);
-                       if (!empty($enableCondition)) {
-                               $where .= ' AND ' . $enableCondition;
-                       }
-                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, $where);
-                               // Arrange overlay records according to transOrigPointerField, so that it's easy to relate them to the originals
-                               // This structure is actually a 2-dimensional array, with the pid as the second key
-                               // Because of versioning, there may be several overlays for a given original and matching the pid too
-                               // ensures that we are referring to the correct overlay
-                       while (($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
-                                       // Perform version overlays, if needed
-                               if ($doVersioning) {
-                                       $GLOBALS['TSFE']->sys_page->versionOL($table, $row);
-                               }
-                                       // The versioned record may actually be FALSE if it is meant to be deleted
-                                       // in the workspace. To be really clean, unset it.
-                               if ($row !== FALSE) {
-                                       if (!isset($overlays[$row[$tableCtrl['transOrigPointerField']]])) {
-                                               $overlays[$row[$tableCtrl['transOrigPointerField']]] = array();
-                                       }
-                                       $overlays[$row[$tableCtrl['transOrigPointerField']]][$row['pid']] = $row;
-                               }
-                       }
-                       $GLOBALS['TYPO3_DB']->sql_free_result($res);
-               }
-               return $overlays;
-       }
-
-       /**
-        * This method is used to retrieve all the records for overlaying other records
-        * when those records are stored in a different table than the originals
-        *
-        * @param       string          $table: name of the table for which to fetch the records
-        * @param       array           $uids: array of all uid's of the original records for which to fetch the translation
-        * @param       integer         $currentLanguage: uid of the system language to translate to
-        * @param       boolean         $doVersioning: true if versioning overlay must be performed
-        * @return      array           All overlay records arranged per original uid and per pid, so that they can be checked (this is related to workspaces)
-        */
-       public static function getForeignOverlayRecords($table, $uids, $currentLanguage, $doVersioning = FALSE) {
-               $overlays = array();
-               if (is_array($uids) && count($uids) > 0) {
-                       $tableCtrl = $GLOBALS['TCA'][$table]['ctrl'];
-                               // Select overlays for all records
-                       $where = $tableCtrl['languageField'] . ' = ' . intval($currentLanguage) .
-                               ' AND ' . $tableCtrl['transOrigPointerField'] . ' IN (' . implode(', ', $uids) . ')';
-                       $enableCondition = self::getEnableFieldsCondition($table);
-                       if (!empty($enableCondition)) {
-                               $where .= ' AND ' . $enableCondition;
-                       }
-                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, $where);
-                               // Arrange overlay records according to transOrigPointerField, so that it's easy to relate them to the originals
-                       while (($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
-                                       // Perform version overlays, if needed
-                               if ($doVersioning) {
-                                       $GLOBALS['TSFE']->sys_page->versionOL($table, $row);
-                               }
-                                       // The versioned record may actually be FALSE if it is meant to be deleted
-                                       // in the workspace. To be really clean, unset it.
-                               if ($row !== FALSE) {
-                                       $overlays[$row[$tableCtrl['transOrigPointerField']]] = $row;
-                               }
-                       }
-                       $GLOBALS['TYPO3_DB']->sql_free_result($res);
-               }
-               return $overlays;
-       }
-
-       /**
-        * This method takes a record and its overlay and performs the overlay according to active translation rules
-        * This piece of code is extracted from t3lib_page::getRecordOverlay()
-        *
-        * @param       string  $table: name of the table for which the operation is taking place
-        * @param       array   $record: record to overlay
-        * @param       array   $overlay: overlay of the record
-        * @return      array   Overlaid record
-        */
-       public static function overlaySingleRecord($table, $record, $overlay) {
-               $overlaidRecord = $record;
-               $overlaidRecord['_LOCALIZED_UID'] = $overlay['uid'];
-               foreach ($record as $key => $value) {
-                       if ($key != 'uid' && $key != 'pid' && isset($overlay[$key])) {
-                               $l10mMode = self::getL10nModeForColumn($table, $key);
-                               if (empty($l10mMode)) {
-                                       $overlaidRecord[$key] = $overlay[$key];
-                               } else {
-                                       if ($l10mMode != 'exclude' && ($l10mMode != 'mergeIfNotBlank' || strcmp(trim($overlay[$key]), ''))) {
-                                               $overlaidRecord[$key] = $overlay[$key];
-                                       }
-                               }
-                       }
-               }
-               return $overlaidRecord;
-       }
-
-       /**
-        * Gets the l10n_mode value, taking TYPO3 CMS versions into account.
-        *
-        * @param string $table Name of the table being looked up
-        * @param string $column Name of the column being looked up
-        * @return string Value of the l10n_mode property, a blank string if undefined
-        */
-       public function getL10nModeForColumn($table, $column) {
-               // Prior to TYPO3 CMS 6.1, l10n_mode is stored in a special TCA cache
-               if (isset($GLOBALS['TSFE']->TCAcachedExtras)) {
-                       return (isset($GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$column])) ? $GLOBALS['TSFE']->TCAcachedExtras[$table]['l10n_mode'][$column] : '';
-
-               // As of TYPO3 CMS 6.1, the full TCA is always loaded
-               } else {
-                       return (isset($GLOBALS['TCA'][$table]['columns'][$column]['l10n_mode'])) ? $GLOBALS['TCA'][$table]['columns'][$column]['l10n_mode'] : '';
-               }
-       }
-}
-?>
\ No newline at end of file
diff --git a/ext_autoload.php b/ext_autoload.php
deleted file mode 100644 (file)
index f352cad..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-/* 
- * Register necessary class names with autoloader
- *
- * $Id$
- */
-$extensionPath = t3lib_extMgm::extPath('overlays');
-return array(
-       'tx_overlays' => $extensionPath . 'class.tx_overlays.php',
-);
-?>
index ad122aa..ffd49da 100644 (file)
@@ -27,22 +27,22 @@ $EM_CONF[$_EXTKEY] = array (
   'clearCacheOnLoad' => 0,
   'lockType' => '',
   'author_company' => '',
-  'version' => '2.3.0',
-  'constraints' => 
+  'version' => '3.0.0-dev',
+  'constraints' =>
   array (
-    'depends' => 
+    'depends' =>
     array (
-      'typo3' => '4.5.0-6.2.99',
+      'typo3' => '6.2.0-7.4.99',
     ),
-    'conflicts' => 
+    'conflicts' =>
     array (
     ),
-    'suggests' => 
+    'suggests' =>
     array (
     ),
   ),
   '_md5_values_when_last_written' => 'a:7:{s:9:"ChangeLog";s:4:"6aac";s:21:"class.tx_overlays.php";s:4:"192f";s:16:"ext_autoload.php";s:4:"ad6d";s:12:"ext_icon.gif";s:4:"73e0";s:10:"README.txt";s:4:"b729";s:14:"doc/manual.pdf";s:4:"f295";s:14:"doc/manual.sxw";s:4:"622c";}',
-  'suggests' => 
+  'suggests' =>
   array (
   ),
   'comment' => 'Verified compatibility with TYPO3 CMS 6.2; added API for getting single record.',
diff --git a/ext_icon.gif b/ext_icon.gif
deleted file mode 100644 (file)
index c92f23f..0000000
Binary files a/ext_icon.gif and /dev/null differ
diff --git a/ext_icon.png b/ext_icon.png
new file mode 100644 (file)
index 0000000..f47a929
Binary files /dev/null and b/ext_icon.png differ