/**
  * HTTP entry point to validate a record. The model name string must be
  * described in $can_validate, or a 404 will be returned.  POST data will
  * indicate what to run validation on.
  *
  * @param string  $model_name
  */
 public function validate_record($model_name)
 {
     if ($this->method != 'POST' && $this->method != 'GET') {
         show_error("Invalid method", 405);
     }
     $model_name = strtolower($model_name);
     if (!isset($this->can_validate[$model_name])) {
         show_404();
     }
     // get the table object
     $tbl = Doctrine::getTable($this->can_validate[$model_name]);
     // run validation
     $errs = $this->do_validate($tbl, $this->input_all);
     // response
     $data = array('success' => true, 'message' => '');
     if (count($errs)) {
         $data['success'] = false;
         $data['message'] = count($errs) . " validation errors: ";
         $data['message'] .= implode('; ', array_values($errs));
         $data['errors'] = $errs;
         $data['conflict'] = array();
         // lookup any existing stuff that caused unique conflicts
         foreach ($errs as $fld => $err) {
             if ($err == 'unique' && isset($this->return_conflicting[$fld])) {
                 $relname = $this->return_conflicting[$fld];
                 $with = $tbl->findOneBy($fld, $this->input_all[$fld]);
                 if ($with) {
                     $with = $relname === true ? $with->toArray() : $with[$relname]->toArray();
                     air2_clean_radix($with);
                     $data['conflict'][$fld] = $with;
                 }
             }
         }
     }
     $this->response($data);
 }
/**
 * Unset array of data based on AIR2 column name conventions
 *
 * @param associative-array $radix
 * @param array   $whitelist
 */
function air2_clean_radix(&$radix, $whitelist = array())
{
    foreach ($radix as $key => &$val) {
        if (is_array($val)) {
            // recursively clean subobjects
            air2_clean_radix($val, $whitelist);
        } else {
            // skip whitelist
            if (in_array($key, $whitelist)) {
                continue;
            }
            // unset cre/upd user id's, passwords, and PK/FK id's
            if (preg_match('/_cre_user$/', $key) || preg_match('/_upd_user$/', $key) || preg_match('/_password$/', $key) || preg_match('/_id$/', $key)) {
                unset($radix[$key]);
            }
        }
    }
}
 /**
  * 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);
 }
 /**
  * Attempt to fetch conflict-with existing record from database
  *
  * @param type    $key
  * @param type    $confl
  * @return type
  */
 private function _get_with($key, $confl)
 {
     $mname = TankSource::get_model_for($key);
     if ($mname && isset($confl['uuid'])) {
         if ($mname != 'SrcFact') {
             $rec = AIR2_Record::find($mname, $confl['uuid']);
             if ($rec) {
                 $data = $rec->toArray();
                 air2_clean_radix($data);
                 return $data;
             }
         } else {
             // facts suck ... src_id.fact_id ... use raw sql for speed!
             $ids = explode('.', $confl['uuid']);
             if ($ids && count($ids) == 2) {
                 $conn = AIR2_DBManager::get_connection();
                 $s = 'f.fact_id, f.fact_name, f.fact_identifier, f.fact_fv_type, ' . 'afv.fv_value as analyst_fv, sfv.fv_value as source_fv, ' . 'sf.sf_src_value as source_text, sf.sf_lock_flag';
                 $f = 'src_fact sf join fact f on (sf.sf_fact_id=f.fact_id) left ' . 'join fact_value afv on (sf.sf_fv_id=afv.fv_id) left join ' . 'fact_value sfv on (sf.sf_src_fv_id=sfv.fv_id)';
                 $w = 'sf_src_id=? and sf_fact_id=?';
                 $rs = $conn->fetchRow("select {$s} from {$f} where {$w}", array($ids[0], $ids[1]));
                 if ($rs) {
                     return $rs;
                 }
             }
         }
     }
     return false;
 }