From 84e703a0a1536e49929f5244167d2d158dd1c7d6 Mon Sep 17 00:00:00 2001
From: Oliver Hader <oliver@typo3.org>
Date: Wed, 19 Feb 2014 14:17:11 +0100
Subject: [PATCH] [FEATURE] Introduce MM_oppositeUsage property

On copying a sys_category record, a new MM reference is created,
however without setting the "fieldname". This value is basically
defined from the opposite entity with MM_match_fields, but
cannot be accessed.

This change introduces the MM_oppositeUsage property for MM
definitions in the TCA.

Example:
'config' => array(
  'allowed' => '*',
  'MM' => 'tx_myextension_first_second_mm',
  'MM_oppositeUsage' => array(
    'tt_content' => array('somefield'),
    'tx_myextension_domain_model' => array('some_property'),
  ),
),

Resolves: #56061
Documentation: #56123
Releases: 6.2
Change-Id: I26fd54688cf44d6a026ccdb3ca9276583b32acd3
Reviewed-on: https://review.typo3.org/27677
Reviewed-by: Wouter Wolters
Reviewed-by: Ernesto Baschny
Tested-by: Wouter Wolters
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
---
 .../core/Classes/Database/RelationHandler.php | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/typo3/sysext/core/Classes/Database/RelationHandler.php b/typo3/sysext/core/Classes/Database/RelationHandler.php
index a7a6c24591dd..9a2b4e82179c 100644
--- a/typo3/sysext/core/Classes/Database/RelationHandler.php
+++ b/typo3/sysext/core/Classes/Database/RelationHandler.php
@@ -206,6 +206,13 @@ class RelationHandler {
 	 */
 	public $MM_table_where = '';
 
+	/**
+	 * Usage of a MM field on the opposite relation.
+	 *
+	 * @var array
+	 */
+	protected $MM_oppositeUsage;
+
 	/**
 	 * @var boolean
 	 */
@@ -239,6 +246,9 @@ class RelationHandler {
 		$this->MM_match_fields = is_array($conf['MM_match_fields']) ? $conf['MM_match_fields'] : array();
 		$this->MM_insert_fields = is_array($conf['MM_insert_fields']) ? $conf['MM_insert_fields'] : $this->MM_match_fields;
 		$this->currentTable = $currentTable;
+		if (!empty($conf['MM_oppositeUsage']) && is_array($conf['MM_oppositeUsage'])) {
+			$this->MM_oppositeUsage = $conf['MM_oppositeUsage'];
+		}
 		if ($this->MM_is_foreign) {
 			$tmp = $conf['type'] === 'group' ? $conf['allowed'] : $conf['foreign_table'];
 			// Normally, $conf['allowed'] can contain a list of tables,
@@ -595,6 +605,7 @@ class RelationHandler {
 					$insertFields[$sorting_field] = $c;
 					if ($tablename) {
 						$insertFields['tablenames'] = $tablename;
+						$insertFields = $this->completeOppositeUsageValues($tablename, $insertFields);
 					}
 					$GLOBALS['TYPO3_DB']->exec_INSERTquery($MM_tableName, $insertFields);
 					if ($this->MM_is_foreign) {
@@ -1038,4 +1049,33 @@ class RelationHandler {
 			&& $parentConf['symmetric_field']
 			&& $parentUid == $childRec[$parentConf['symmetric_field']];
 	}
+
+	/**
+	 * Completes MM values to be written by values from the opposite relation.
+	 * This method used MM insert field or MM match fields if defined.
+	 *
+	 * @param string $tableName Name of the opposite table
+	 * @param array $referenceValues Values to be written
+	 * @return array Values to be written, possibly modified
+	 */
+	protected function completeOppositeUsageValues($tableName, array $referenceValues) {
+		if (empty($this->MM_oppositeUsage[$tableName]) || count($this->MM_oppositeUsage[$tableName]) > 1) {
+			return $referenceValues;
+		}
+
+		$fieldName = $this->MM_oppositeUsage[$tableName][0];
+		if (empty($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'])) {
+			return $referenceValues;
+		}
+
+		$configuration = $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'];
+		if (!empty($configuration['MM_insert_fields'])) {
+			$referenceValues = array_merge($configuration['MM_insert_fields'], $referenceValues);
+		} elseif (!empty($configuration['MM_match_fields'])) {
+			$referenceValues = array_merge($configuration['MM_match_fields'], $referenceValues);
+		}
+
+		return $referenceValues;
+	}
+
 }
-- 
GitLab