Project

General

Profile

Bug #79635 » processRemapStack.php

Thomas Hohn, 2017-03-09 13:15

 
/**
* Processes the $this->remapStack at the end of copying, inserting, etc. actions.
* The remapStack takes care about the correct mapping of new and old uids in case of relational data.
*
* @return void
*/
public function processRemapStack()
{
static $count;
// Processes the remap stack:
if (is_array($this->remapStack)) {
$remapFlexForms = [];

foreach ($this->remapStack as $remapAction) {

// If no position index for the arguments was set, skip this remap action:
if (!is_array($remapAction['pos'])) {
continue;
}
// Load values from the argument array in remapAction:
$field = $remapAction['field'];
$id = $remapAction['args'][$remapAction['pos']['id']];
$rawId = $id;
$table = $remapAction['args'][$remapAction['pos']['table']];
$valueArray = $remapAction['args'][$remapAction['pos']['valueArray']];
$tcaFieldConf = $remapAction['args'][$remapAction['pos']['tcaFieldConf']];
$additionalData = $remapAction['additionalData'];
// The record is new and has one or more new ids (in case of versioning/workspaces):
if (strpos($id, 'NEW') !== false) {
// Replace NEW...-ID with real uid:
$id = $this->substNEWwithIDs[$id];
// If the new parent record is on a non-live workspace or versionized, it has another new id:
if (isset($this->autoVersionIdMap[$table][$id])) {
$id = $this->autoVersionIdMap[$table][$id];
}
$remapAction['args'][$remapAction['pos']['id']] = $id;
}
// Replace relations to NEW...-IDs in field value (uids of child records):
if (is_array($valueArray)) {
foreach ($valueArray as $key => $value) {
if (strpos($value, 'NEW') !== false) {
if (strpos($value, '_') === false) {
$affectedTable = $tcaFieldConf['foreign_table'];
$prependTable = false;
} else {
$parts = explode('_', $value);
$value = array_pop($parts);
$affectedTable = implode('_', $parts);
$prependTable = true;
}
$value = $this->substNEWwithIDs[$value];
// The record is new, but was also auto-versionized and has another new id:
if (isset($this->autoVersionIdMap[$affectedTable][$value])) {
$value = $this->autoVersionIdMap[$affectedTable][$value];
}
if ($prependTable) {
$value = $affectedTable . '_' . $value;
}
// Set a hint that this was a new child record:
$this->newRelatedIDs[$affectedTable][] = $value;
$valueArray[$key] = $value;
}
}
$remapAction['args'][$remapAction['pos']['valueArray']] = $valueArray;
}
// Process the arguments with the defined function:
$newValue = call_user_func_array([$this, $remapAction['func']], $remapAction['args']);
// If array is returned, check for maxitems condition, if string is returned this was already done:
if (is_array($newValue)) {
$newValue = implode(',', $this->checkValue_checkMax($tcaFieldConf, $newValue));
// The reference casting is only required if
// checkValue_group_select_processDBdata() returns an array
$newValue = $this->castReferenceValue($newValue, $tcaFieldConf);
}
// Update in database (list of children (csv) or number of relations (foreign_field)):
if (!empty($field)) {
$this->updateDB($table, $id, [$field => $newValue]);
// Collect data to update FlexForms
} elseif (!empty($additionalData['flexFormId']) && !empty($additionalData['flexFormPath'])) {
$flexFormId = $additionalData['flexFormId'];
$flexFormPath = $additionalData['flexFormPath'];

if (!isset($remapFlexForms[$flexFormId])) {
$remapFlexForms[$flexFormId] = [];
}

$remapFlexForms[$flexFormId][$flexFormPath] = $newValue;
}

// Process waiting Hook: processDatamap_afterDatabaseOperations:
if (isset($this->remapStackRecords[$table][$rawId]['processDatamap_afterDatabaseOperations'])) {


$hookArgs = $this->remapStackRecords[$table][$rawId]['processDatamap_afterDatabaseOperations'];
// Update field with remapped data:
$hookArgs['fieldArray'][$field] = $newValue;
// Process waiting hook objects:
$hookObjectsArr = $hookArgs['hookObjectsArr'];
foreach ($hookObjectsArr as $hookObj) {
if (method_exists($hookObj, 'processDatamap_afterDatabaseOperations')) {
$fp = fopen("processRemapStack.log", "a+");
fwrite($fp, "ProcessRemapStack " . $hookArgs['status'] . ' ' . $table . ' ' . $rawId . ' ' . $count . PHP_EOL);
fwrite($fp, print_r($hookArgs['fieldArray'], true) . PHP_EOL);
fclose($fp);
$hookObj->processDatamap_afterDatabaseOperations($hookArgs['status'], $table, $rawId, $hookArgs['fieldArray'], $this);
$hookObj->processDatamap_afterDatabaseOperations($hookArgs['status'], $table, $rawId, $hookArgs['fieldArray'], $this);
}
}
}
}

if ($remapFlexForms) {
foreach ($remapFlexForms as $flexFormId => $modifications) {
$this->updateFlexFormData($flexFormId, $modifications);
}
}
$count++;
}
// Processes the remap stack actions:
if ($this->remapStackActions) {
foreach ($this->remapStackActions as $action) {
if (isset($action['callback']) && isset($action['arguments'])) {
call_user_func_array($action['callback'], $action['arguments']);
}
}
}
// Processes the reference index updates of the remap stack:
foreach ($this->remapStackRefIndex as $table => $idArray) {
foreach ($idArray as $id) {
$this->updateRefIndex($table, $id);
unset($this->remapStackRefIndex[$table][$id]);
}
}
// Reset:
$this->remapStack = [];
$this->remapStackRecords = [];
$this->remapStackActions = [];
$this->remapStackRefIndex = [];
}
(1-1/2)