/** * Merge 2 source records together, including all related data. * * @param Source $prime the record to merge into (will be preserved) * @param Source $merge the record to merge from (will be deleted) * @param array $options (optional) options to use in merging conflicting data * @param boolean $commit (optional) * @return boolean|string|array */ public static function merge($prime, $merge, $options = array(), $commit = false) { self::$MERGE_OPTS = $options; self::$MERGE_RESULT = array('errs' => array(), 'prime' => array(), 'merge' => array(), 'moved' => array(), 'skipped' => array()); // make sure we have fresh objects $prime->clearRelated(); $merge->clearRelated(); // start a transaction $conn = AIR2_DBManager::get_master_connection(); $conn->beginTransaction(); // run the merges try { self::merge_source($prime, $merge); self::merge_facts($prime, $merge); // remaining data produces no errors... so only run on commit if ($commit) { self::merge_easy($prime, $merge); self::combine_orgs($prime, $merge); self::combine_stat($prime, $merge); } // delete the merged source $merge->delete(); } catch (Exception $e) { $conn->rollback(); self::$MERGE_RESULT['fatal_error'] = $e->getMessage(); return self::$MERGE_RESULT['fatal_error']; } // cache the merge result self::$MERGE_RESULT['result'] = $prime->toArray(true); // commit or rollback $errors = self::$MERGE_RESULT['errs']; if (count($errors) == 0 && $commit) { $conn->commit(); } else { $conn->rollback(); $prime->clearRelated(); $prime->refresh(); $merge->clearRelated(); $merge->refresh(); } // return errors or true on success if (count($errors) > 0) { return $errors; } else { return true; } }
/** * Run a merge using the AIR2Merge library. * * @param array $response_data */ protected function run($response_data = array()) { // turn off logging during the merge $was_logging_enabled = AIR2Logger::$ENABLE_LOGGING; AIR2Logger::$ENABLE_LOGGING = false; // run the merge and reset logging $type = $this->my_type; $errs = AIR2Merge::merge($this->prime, $this->merge, $this->ops, $this->commit_on_success); $result = AIR2Merge::get_result(); AIR2Logger::$ENABLE_LOGGING = $was_logging_enabled; // what happened? $status = 200; if ($errs === true) { $response_data['success'] = true; $response_data['message'] = "Successfully merged {$type}s"; // attach the "merged" object to data $response_data['ResultSource'] = $result['result']; air2_clean_radix($response_data['ResultSource'], $this->radix_whitelist); // attach ops used $response_data['op_prime'] = $result['prime']; $response_data['op_merge'] = $result['merge']; // log the merge if ($this->commit_on_success) { $this->log_activity($result, $response_data); } } elseif (is_string($errs)) { $response_data['success'] = false; $response_data['message'] = $errs; $status = 500; } else { $response_data['success'] = false; $response_data['message'] = "Unable to merge {$type}s"; $response_data['errors'] = $errs; $status = 400; // attach ops used $response_data['op_prime'] = $result['prime']; $response_data['op_merge'] = $result['merge']; } // attach fact data $rs = AIR2_DBManager::get_connection()->fetchAll('select * from fact'); $response_data['facts'] = array(); foreach ($rs as $row) { $response_data['facts'][$row['fact_id']] = $row; } // respond with data $this->response($response_data, $status); }