/** * Diff's two repository resources. IMPORTANT: This function assumes that there is a total order over the key field and that they are sorted by the keyfield ascending! Basically it assumes that the key field is an integer aswell! * * @param Tx_Contentstage_Domain_Repository_Result $resource1 The original (target) resource. * @param Tx_Contentstage_Domain_Repository_Result $resource2 The changed (source) resource. * @param array $differences The difference array, passed this way for recursions etc. * @param string $keyField The key field of each row (usually uid). * @param string $table The table to perform the diff for. Is only used to hide certain fields. Defaults to pages. * @return array An array with keys for each $keyField found in either (or both) of the resources. These arrays contain an array with differences for each field or a lone message if the row was missing entirely. */ public function &resources(Tx_Contentstage_Domain_Repository_Result &$resource1 = null, Tx_Contentstage_Domain_Repository_Result &$resource2 = null, array &$differences = array(), $keyField = 'uid', $pidField = 'pid') { $differences = array('byPid' => array()); $r1 = $resource1->nextResolved(); $r2 = $resource2->nextResolved(); $table = $resource1->getTable(); $tableTCA = $this->tca->getProcessedTca($table); $fromRepository = $resource1->getRepository(); $toRepository = $resource2->getRepository(); $lateBinding = $resource1->getLateBindingFields() !== false && $resource2->getLateBindingFields(); while (true) { if ($r1 === false && $r2 === false) { break; } $uid1 = $r1 === false ? PHP_INT_MAX : $r1[$keyField]; $uid2 = $r2 === false ? PHP_INT_MAX : $r2[$keyField]; $r1Next = $r2Next = false; $uid = min($uid1, $uid2); if ($uid1 < $uid2) { $r1 = $resource1->currentResolvedWithLateBindings(); $differences[$uid]['_sourceMissing'] = $this->wrap($this->translate('diff.source.recordMissing', array($keyField, $uid)), true); $r1Next = true; $this->maximumTargetTstamp = max($this->maximumTargetTstamp, intval($r1[$tableTCA['__tstampField']])); } else { if ($uid2 < $uid1) { $r2 = $resource2->currentResolvedWithLateBindings(); $differences[$uid]['_targetMissing'] = $this->wrap($this->translate('diff.target.recordMissing', array($keyField, $uid))); $r2Next = true; $this->maximumSourceTstamp = max($this->maximumSourceTstamp, intval($r2[$tableTCA['__tstampField']])); } else { $diffRows = !$lateBinding; if ($lateBinding && $r1['hash'] !== $r2['hash']) { $r1 = $resource1->currentResolvedWithLateBindings(); $r2 = $resource2->currentResolvedWithLateBindings(); $diffRows = true; } if ($diffRows) { $this->rows($r1, $r2, $differences, $keyField, $table); } foreach (array('files', 'folders', 'softrefs') as $type) { if (!is_array($tableTCA['__' . $type])) { continue; } foreach ($tableTCA['__' . $type] as $field => $true) { if (!isset($differences[$uid][$field])) { // no difference, let's check the files if ($type === 'softrefs') { $folder = ''; $function = 'compareFiles'; $values = array(); $this->tca->resolveSoftRefUids($fromRepository, $table, $field, $r1, $values); $singleValues = is_array($values['__FILE']) ? array_keys($values['__FILE']) : array(); } else { $folder = $tableTCA[$field]['folder']; $function = 'compare' . ucfirst($type); $singleValues = t3lib_div::trimExplode(',', $r1[$field], true); } foreach ($singleValues as $value) { $message = $toRepository->{$function}($fromRepository->getFileHandle($folder . $value), $toRepository->getFileHandle($folder . $value)); if ($message !== false) { $differences[$uid][$field] .= $this->wrap($message); } } } } } $r1Next = $r2Next = true; } } if (!empty($differences[$uid])) { $differences['byPid'][$r1 === false ? $r2[$pidField] : $r1[$pidField]][$uid] =& $differences[$uid]; } if ($r1Next) { $r1 = $resource1->nextResolved(); } if ($r2Next) { $r2 = $resource2->nextResolved(); } } return $differences; }
/** * Insert/update a given resource in the table. The resource must have the same fields, e.g. should be from the same table in another db. * * @param Tx_Contentstage_Domain_Repository_Result $resource The db resource to get the data from. * @return void. * @throws Exception */ public function insert(Tx_Contentstage_Domain_Repository_Result $resource) { $buffer = array(); $c = 0; $updateTerm = false; $fields = array(); $table = $resource->getTable(); while (($row = $resource->nextWithRelations()) !== false) { $buffer[] = $row; //$this->log->log($table, Tx_CabagExtbase_Utility_Logging::INFORMATION, $row); if ($updateTerm === false) { $fields = array_keys($row); $update = array(); foreach ($fields as &$field) { $update[] = $field . ' = VALUES(' . $field . ')'; } $updateTerm = implode(',', $update); } if ($c % 100 === 0) { $this->_insert($table, $buffer, $fields, $updateTerm); $buffer = array(); } $c++; } // if no row was looped, fields/updateTerm are not set, but that does not matter $this->_insert($table, $buffer, $fields, $updateTerm); }