Exemplo n.º 1
0
function doDetailInsertion($recordID, $details, $recordType, $wg, &$nonces, &$retitleRecs, $modeImport)
{
    /* $nonces :  nonce-to-bibID mapping, makes it possible to resolve recDetails values of reference variety */
    /* $retitleRecs : set of records whos titles could be out of date and need recalc */
    /*
     * $details is the form
     *    $details = array("t:1" => array("bd:234463" => "7th Ave"),
     *                      ,,,
     *                     "t:11" => array("0" => "p POINT(-73.951172 40.805661)"));
     * where t:id means detail type id  and bd:id means detail record id
     * new details are array values without a preceeding detail ID as in the last line of this example
     */
    $dtyIDs = array();
    // do a double-pass to grab the expected varieties for each bib-detail-type we encounter, along with other constraints
    foreach ($details as $dtyID => $pairs) {
        if (substr($dtyID, 0, 2) != "t:") {
            continue;
        }
        if (!($bdtID = intval(substr($dtyID, 2)))) {
            continue;
        }
        array_push($dtyIDs, $bdtID);
    }
    $dtyVarieties = mysql__select_assoc("defDetailTypes", "dty_ID", "dty_Type", "dty_ID in (" . join($dtyIDs, ",") . ")");
    if ($modeImport != 2) {
        //import without check of record type structure
        //TODO saw: need to change this to include min value or perhaps we let it go and allow saving the min across multiple saves.
        $repeats = mysql__select_assoc("defRecStructure", "rst_DetailTypeID", "rst_MaxValues", "rst_RecTypeID=" . $recordType);
        //            $repeats = mysql__select_assoc("defRecStructure", "rst_DetailTypeID", "rst_MaxValues", "rst_DetailTypeID in (" . join($dtyIDs, ",") . ") and rst_RecTypeID=" . $recordType);
    }
    /*****DEBUG****/
    //error_log("repeats = ".print_r($repeats,true));
    /*****DEBUG****/
    //error_log("details = ".print_r($details,true));
    $updateIDs = array();
    $updateQueries = array();
    $insertQueryValues = array();
    $badIdInsertQueryValues = array();
    $deleteIDs = array();
    $ignoreIDs = array();
    $translated = array();
    $translatedIDs = array();
    // second pass to divide the work up in to inserts, updates, deletes, translates and ignores
    foreach ($details as $dtyID => $pairs) {
        if (substr($dtyID, 0, 2) != "t:") {
            continue;
        }
        // skip any non t: or non type designators
        if (!($bdtID = intval(substr($dtyID, 2)))) {
            continue;
        }
        // invalid (non integer) type id so skip it
        $firstDetail = true;
        foreach ($pairs as $bdID => $val) {
            if (substr($bdID, 0, 3) == "bd:") {
                // this detail corresponds to an existing recDetails: remember its existing dtl_ID
                if (!($bdID = intval(substr($bdID, 3)))) {
                    continue;
                }
                // invalid (non integer) id so skip it
                // check detail exist for the given record
                $resDtl = mysql_query("select dtl_DetailTypeID from recDetails where dtl_RecID = {$recordID} and dtl_ID = {$bdID}");
                if (mysql_num_rows($resDtl) == 1) {
                    $dtlTypeID = mysql_fetch_row($resDtl);
                    if ($dtlTypeID[0] != $bdtID) {
                        // invalid type supplied so skip and give warning
                        warnSaveRec("invalid detail type supplied {$bdtID} for existing detail, did not update detail id {$bdID} ignoring");
                        array_push($ignoreIDs, $bdID);
                        continue;
                    }
                } else {
                    // no existing dtl id for the given record so change this to insert and give warning.
                    warnSaveRec("detail id {$bdID} is not part of record {$recordID}, inserting new detail instead");
                    $oldBdID = $bdID;
                    $bdID = false;
                    // fail test differently to signal translate
                }
            } else {
                // simple case: this is a new detail (no existing dtl_ID) it assumes an array index number
                if ($bdID != intval($bdID)) {
                    continue;
                }
                //bd155  is not equal to 155 while if this is an array index $bdID is numeric
                $bdID = "";
                //signal insert
            }
            $val = trim($val);
            $bdVal = $bdFileID = $bdGeo = "NULL";
            if ($modeImport != 2) {
                //import without check of record type structure
                //check max limit constraints
                if (!array_key_exists($bdtID, $repeats)) {
                    //if no entry in repeats then extra detail
                    /*****DEBUG****/
                    //error_log("non rectype detail type $bdtID found");
                    warnSaveRec("non rectype detail type {$bdtID} found");
                } else {
                    if (is_numeric($repeats[$bdtID])) {
                        if ($repeats[$bdtID] >= 1) {
                            $repeats[$bdtID] = $repeats[$bdtID] - 1;
                            // decrement to reduce limit count NOTE: assumes that all details are given to save
                        } else {
                            if ($firstDetail && $repeats[$bdtID] == 0) {
                                // case of not allowed
                                warnSaveRec("detail type supplied {$bdtID} is not allowed, marking detail id {$bdID} for delete");
                                continue;
                            } else {
                                warnSaveRec("hit max for detail type supplied {$bdtID} , ignoring update detail id {$bdID}");
                                array_push($ignoreIDs, $bdID);
                            }
                        }
                    }
                }
            }
            switch ($dtyVarieties[$bdtID]) {
                case "integer":
                    // these should no logner exist, retained for backward compatibility
                    // bug: non-integer values are not saved
                    if (intval($val) || $val == "0") {
                        $bdVal = intval($val);
                    } else {
                        if ($bdID) {
                            //not integer so ignore
                            array_push($ignoreIDs, $bdID);
                            continue;
                        }
                    }
                    break;
                case "float":
                    if (floatval($val) || preg_match('/^0(?:[.]0*)?$/', $val)) {
                        $bdVal = floatval($val);
                    } else {
                        if ($bdID) {
                            //not a float so ignore
                            array_push($ignoreIDs, $bdID);
                            continue;
                        }
                    }
                    break;
                case "freetext":
                case "blocktext":
                case "date":
                case "year":
                case "urlinclude":
                    // these (year and urlinclude) should no logner exist, retained for backward compatibility
                    if (!$val) {
                        //TODO: SAW check if this includes setting a string to "". if so perhaps this is a second pass delete
                        if ($bdID) {
                            array_push($ignoreIDs, $bdID);
                        }
                        continue;
                    }
                    $bdVal = "'" . addslashes($val) . "'";
                    break;
                case "boolean":
                    // these should no logner exist, retained for backward compatibility
                    $bdVal = $val && $val != "0" ? "'true'" : "'false'";
                    break;
                case "enum":
                case "relationtype":
                    //saw TODO: change this to call validateEnumTerm(RectypeID, DetailTypeID) also Term limits
                    // also may need to separate enum from relationtype
                    // validate that the id is for the given detail type.
                    /*if (mysql_num_rows(mysql_query("select trm_ID from defTerms
                      left join defDetailTypes on dty_NativeVocabID = trm_VocabID
                      where dty_ID=$bdtID and trm_ID='".$val."'")) <= 0) {
                      jsonError("invalid enumeration value \"$val\"");
                      }
                      */
                    $bdVal = "'" . $val . "'";
                    break;
                case "resource":
                    // check that the given resource exists and is fit to point to
                    if ($val[0] == "#") {
                        // a nonce value -- find the appropriate bibID
                        if ($nonces && $nonces[$val]) {
                            $val = $nonces[$val];
                            if (is_array($retitleRecs)) {
                                array_push($retitleRecs, $val);
                            }
                        } else {
                            errSaveRec("invalid resource reference '" . $val . "' for detail type '" . $bdtID);
                            return array("error" => "recordID = {$recordID} rectype = {$recordType} detailtype = {$bdtID}" . ($bdID ? " detailID = {$bdID}" : ""));
                        }
                    }
                    //FIXME :saw  change this to check for superuser and valid recID or valid and viewable record for current user.
                    if (mysql_num_rows(mysql_query("select rec_ID from Records where (! rec_OwnerUGrpID or rec_OwnerUGrpID={$wg}) and rec_ID=" . intval($val))) <= 0) {
                        //	jsonError("invalid resource #".intval($val));
                    }
                    $bdVal = intval($val);
                    break;
                case "file":
                    if (is_numeric($val)) {
                        //this is ulf_ID
                        $ulf_ID = intval($val);
                    } else {
                        // new way - URL or JSON string with file data array (structure similar get_uploaded_file_info)
                        $ulf_ID = register_external($val);
                        //this is URL
                    }
                    if ($ulf_ID == null || mysql_num_rows(mysql_query("select ulf_ID from recUploadedFiles where ulf_ID=" . $ulf_ID)) <= 0) {
                        errSaveRec("invalid file pointer '" . $val . "' for detail type '" . $bdtID);
                        return array("error" => "recordID = {$recordID} rectype = {$recordType} detailtype = {$bdtID}" . ($bdID ? " detailID = {$bdID}" : ""));
                    }
                    $bdFileID = intval($ulf_ID);
                    break;
                case "geo":
                    $geoType = trim(substr($val, 0, 2));
                    $geoVal = trim(substr($val, 2));
                    $res = mysql_query("select geomfromtext('" . addslashes($geoVal) . "') = 'Bad object'");
                    $row = mysql_fetch_row($res);
                    if ($row[0]) {
                        // bad object!  Go stand in the corner.
                        errSaveRec("invalid geographic value '" . $val . "' for detail type '" . $bdtID);
                        return array("error" => "recordID = {$recordID} rectype = {$recordType} detailtype = {$bdtID}" . ($bdID ? " detailID = {$bdID}" : ""));
                    }
                    $bdVal = '"' . addslashes($geoType) . '"';
                    $bdGeo = "geomfromtext('" . addslashes($geoVal) . "')";
                case "separator":
                case "relmarker":
                    continue;
                    //noop since separators and relmarker have no detail values
                    // saw Decide - should we do a relationConstraints check here
                //noop since separators and relmarker have no detail values
                // saw Decide - should we do a relationConstraints check here
                default:
                    // ???
                    if ($bdID) {
                        array_push($ignoreIDs, $bdID);
                    }
                    continue;
            }
            if ($bdID) {
                //danger the following update must restrict to a single detail id.
                //TODO: saw perhaps we should check value the same?
                array_push($updateQueries, "update recDetails set dtl_Value={$bdVal}, dtl_UploadedFileID={$bdFileID}, dtl_Geo={$bdGeo} where dtl_ID={$bdID} and dtl_DetailTypeID={$bdtID} and dtl_RecID={$recordID}");
                array_push($updateIDs, $bdID);
            } else {
                if ($bdID === false) {
                    //bad bdID passed insert detail
                    array_push($badIdInsertQueryValues, "({$recordID}, {$bdtID}, {$bdVal}, {$bdFileID}, {$bdGeo}," . ($modeImport > 0 ? 1 : 0) . ")");
                    $translated[$oldBdID] = array('val' => $val, 'dtType' => $bdtID);
                    array_push($translatedIDs, $oldBdID);
                } else {
                    array_push($insertQueryValues, "({$recordID}, {$bdtID}, {$bdVal}, {$bdFileID}, {$bdGeo}," . ($modeImport > 0 ? 1 : 0) . ")");
                }
            }
            $firstDetail = false;
        }
        //end details values loop for dty
    }
    //end dty loop
    //delete all details except the one that are being updated
    $deleteDetailIDsQuery = "select dtl_ID from recDetails where dtl_RecID={$recordID}";
    if (count($updateIDs)) {
        $deleteDetailIDsQuery .= " and dtl_ID not in (" . join(",", $updateIDs) . ")";
    }
    if (count($ignoreIDs)) {
        $deleteDetailIDsQuery .= " and dtl_ID not in (" . join(",", $ignoreIDs) . ")";
    }
    $resDel = mysql_query($deleteDetailIDsQuery);
    if (mysql_error()) {
        errSaveRec("db error while finding details to be deleted for record ID " . $recordID . " error : " . mysql_error());
        return array("error" => "recordID = {$recordID} rectype = {$recordType} ");
    }
    // find details to be deleted
    if (mysql_num_rows($resDel)) {
        while ($row = mysql_fetch_row($resDel)) {
            array_push($deleteIDs, $row[0]);
        }
    }
    /*****DEBUG****/
    //error_log("ignore detail IDs = ".print_r($ignoreIDs,true));
    /*****DEBUG****/
    //error_log("update detail IDs = ".print_r($updateIDs,true));
    /*****DEBUG****/
    //error_log("delete detail IDs = ".print_r($deleteIDs,true));
    /*	$retval is an array of arrays of detail ids
     *	with an array for deletes, updates and inserts
     *	if they occurred
     */
    $retval = array();
    if (count($ignoreIDs)) {
        $retval["ignored"] = $ignoreIDs;
    }
    //update all details to be kept
    if (count($deleteIDs)) {
        $deleteDetailsQuery = "delete from recDetails where dtl_ID in (" . join(",", $deleteIDs) . ")";
        //            mysql_query($deleteDetailsQuery);
        if (mysql_error()) {
            errSaveRec("db error while deleteing details (" . join(",", $deleteIDs) . ") for record ID " . $recordID . " error : " . mysql_error());
            return array("error" => "recordID = {$recordID} rectype = {$recordType} ");
        }
        //            $retval["deleted"] = $deleteIDs;
    }
    //update all details to be kept
    if (count($updateQueries)) {
        /*****DEBUG****/
        //error_log("in DoInserts updating details ".print_r($updateQueries,true));
        foreach ($updateQueries as $update) {
            mysql_query($update);
            if (mysql_error()) {
                errSaveRec("db error while running '" . $update . "' for record ID " . $recordID . " error : " . mysql_error());
                return array("error" => "recordID = {$recordID} rectype = {$recordType} ");
            }
        }
        $retval["updated"] = $updateIDs;
    }
    if (count($insertQueryValues)) {
        //insert all new details
        /*****DEBUG****/
        //error_log("in DoInserts inserting details ".print_r($inserts,true));
        mysql_query("insert into recDetails (dtl_RecID, dtl_DetailTypeID, dtl_Value, dtl_UploadedFileID, dtl_Geo, dtl_AddedByImport) values " . join(",", $insertQueryValues));
        $first_bd_id = mysql_insert_id();
        if (mysql_error()) {
            errSaveRec("db error while inserting '" . $insertQueryValues . "' for record ID " . $recordID . " error : " . mysql_error());
            return array("error" => "recordID = {$recordID} rectype = {$recordType} ");
        }
        $retval["inserted"] = range($first_bd_id, $first_bd_id + count($insertQueryValues) - 1);
    }
    if (count($badIdInsertQueryValues)) {
        //insert all new details
        /*****DEBUG****/
        //error_log("in DoInserts inserting Bad ID details ".print_r($badIdInsertQueryValues,true));
        $j = 0;
        foreach ($badIdInsertQueryValues as $valueSet) {
            mysql_query("insert into recDetails (dtl_RecID, dtl_DetailTypeID, dtl_Value, dtl_UploadedFileID, dtl_Geo, dtl_AddedByImport) values " . $valueSet);
            if (mysql_error()) {
                errSaveRec("db error while inserting '" . $valueSet . "' for record ID " . $recordID . " error : " . mysql_error());
                return array("error" => "recordID = {$recordID} rectype = {$recordType} ");
            }
            $new_bdID = mysql_insert_id();
            $translated[$translatedIDs[$j]]['new_bdID'] = $new_bdID;
        }
        $retval["translated"] = $translated;
        $retval["translatedIDs"] = $translatedIDs;
    }
    return $retval;
}
Exemplo n.º 2
0
/**
 * copy file from another h3 instance and register it
 *
 * @param mixed $src_fileid - file id in source db
 * @return int - file id in destionation db, null - if copy and registration are failed
 */
function copyRemoteFile($src_fileid)
{
    global $sourcedbname, $dbPrefix, $db_prefix;
    $sourcedb = $db_prefix . $sourcedbname;
    $_src_HEURIST_UPLOAD_DIR = HEURIST_UPLOAD_ROOT . $sourcedbname . '/';
    $res = mysql_query("select * from {$sourcedb}.`recUploadedFiles` where ulf_ID=" . $src_fileid);
    if (mysql_num_rows($res) != 1) {
        print "<div  style='color:red;'>no entry for file id#" . $src_fileid . "</div>";
        return null;
        // nothing returned if parameter does not match one and only one row
    }
    $file = mysql_fetch_assoc($res);
    $need_copy = false;
    $externalFile = false;
    if ($file['ulf_FileName']) {
        $filename = $file['ulf_FilePath'] . $file['ulf_FileName'];
        // post 18/11/11 proper file path and name
        $need_copy = $file['ulf_FilePath'] == $_src_HEURIST_UPLOAD_DIR;
    } else {
        if ($file['ulf_ExternalFileReference']) {
            $filename = $file['ulf_ExternalFileReference'];
            // post 18/11/11 proper file path and name
            $need_copy = false;
            $externalFile = true;
        } else {
            $filename = $_src_HEURIST_UPLOAD_DIR . $file['ulf_ID'];
            // pre 18/11/11 - bare numbers as names, just use file ID
            $need_copy = true;
        }
    }
    if (!$externalFile && !file_exists($filename)) {
        //check if this file is remote
        print "<div  style='color:red;'>File {$filename} not found. Can't register file</div>";
        ob_flush();
        flush();
        // flush to screen
        return null;
    }
    if (false && $externalFile) {
        //@todo - copy external file and save
        $data = loadRemoteURLContent($filename);
        if (!$data) {
            print "<div  style='color:red;'>Error. Can't download {$filename}. Can't register URL</div>";
            ob_flush();
            flush();
            // flush to screen
            return null;
        }
    }
    if ($need_copy) {
        $newfilename = HEURIST_UPLOAD_DIR . $file['ulf_OrigFileName'];
        //if file in source upload dirtectiry copy it to destionation upload directory
        if (!copy($filename, $newfilename)) {
            print "<div  style='color:red;'>Can't copy file {$fielname} to " . HEURIST_UPLOAD_DIR . "</div>";
            ob_flush();
            flush();
            // flush to screen
            return null;
        }
        $filename = $newfilename;
    }
    //returns new file id in dest database
    if ($externalFile) {
        $jsonData = json_encode(array('remoteURL' => $filename, 'ext' => $file['ulf_MimeExt'], 'params' => $file['ulf_Parameters'] ? $file['ulf_Parameters'] : null));
        $ret = register_external($jsonData, null, false);
    } else {
        $ret = register_file($filename, null, false);
    }
    if (intval($ret) > 0) {
        return $ret;
    } else {
        print "<div  style='color:red;'>Can't register file " . $filename . "</div>";
        ob_flush();
        flush();
        // flush to screen
        return null;
    }
}
 function convertPostToMysql($postVal)
 {
     //artem
     if (is_numeric($postVal)) {
         //this is old way - ulf_ID
         return array("dtl_UploadedFileID" => $postVal);
     } else {
         // new way - $postVal - json string with file data array - structure similar get_uploaded_file_info
         $ulf_ID = register_external($postVal);
         //in uploadFile.php
         return $ulf_ID == null ? null : array("dtl_UploadedFileID" => $ulf_ID);
     }
 }
Exemplo n.º 4
0
/**
 * copy file from another vsn 3 instance and register it
 *
 * @param mixed $src_fileid - file id in source db
 * @return int - file id in destionation db, null - if copy and registration are failed
 */
function copyRemoteFile($src_fileid)
{
    global $sourcedbname, $dbPrefix, $db_prefix;
    $sourcedb = $db_prefix . $sourcedbname;
    $_src_HEURIST_FILESTORE_DIR = HEURIST_UPLOAD_ROOT . $sourcedbname . '/';
    $_src_HEURIST_FILES_DIR = HEURIST_UPLOAD_ROOT . $sourcedbname . '/file_uploads/';
    $res = mysql_query("select * from {$sourcedb}.`recUploadedFiles` where ulf_ID=" . $src_fileid);
    if (mysql_num_rows($res) != 1) {
        print "<div  style='color:red;'>no entry (or multiple entries)for file id#" . $src_fileid . "</div>";
        return null;
        // nothing returned if parameter does not match one and only one row
    }
    $file = mysql_fetch_assoc($res);
    $need_copy = false;
    $externalFile = false;
    if (@$file['ulf_FilePath'] || @$file['ulf_FileName']) {
        $path = @$file['ulf_FilePath'] . @$file['ulf_FileName'];
        //add database media storage folder for relative paths
        //$filename = resolveFilePath($filename);
        //the same as in resolveFilePath($filename); however instead of consts uses source db folders
        if ($path && !file_exists($path)) {
            chdir($_src_HEURIST_FILESTORE_DIR);
            // relatively db root  HEURIST_FILESTORE_DIR
            $fpath = realpath($path);
            if (file_exists($fpath)) {
                $filename = $fpath;
            } else {
                chdir($_src_HEURIST_FILES_DIR);
                // relatively file_uploads
                $fpath = realpath($path);
                if (file_exists($fpath)) {
                    $filename = $fpath;
                } else {
                    //special case to support absolute path on file server
                    if (strpos($path, '/srv/HEURIST_FILESTORE/') === 0) {
                        $fpath = str_replace('/srv/HEURIST_FILESTORE/', HEURIST_UPLOAD_ROOT, $path);
                        if (file_exists($fpath)) {
                            $filename = $fpath;
                        }
                    }
                }
            }
        } else {
            $filename = $path;
        }
        $need_copy = true;
    } else {
        if ($file['ulf_ExternalFileReference']) {
            $filename = $file['ulf_ExternalFileReference'];
            // post 18/11/11 proper file path and name
            $need_copy = false;
            $externalFile = true;
        } else {
            $filename = $_src_HEURIST_FILESTORE_DIR . $file['ulf_ID'];
            // pre 18/11/11 - bare numbers as names, just use file ID
            $need_copy = true;
        }
    }
    if (!$externalFile && !file_exists($filename)) {
        //check if this file is remote
        print "<div  style='color:red;'>File {$filename} not found. Can't register file</div>";
        ob_flush();
        flush();
        // flush to screen
        return null;
    }
    if (false && $externalFile) {
        //@todo - copy external file and save
        $data = loadRemoteURLContent($filename);
        if (!$data) {
            print "<div  style='color:red;'>Error. Can't download {$filename}. Can't register URL</div>";
            ob_flush();
            flush();
            // flush to screen
            return null;
        }
    }
    if ($need_copy) {
        $newfilename = HEURIST_FILES_DIR . $file['ulf_OrigFileName'];
        //if file in source upload dirtectiry copy it to destionation upload directory
        if (!copy($filename, $newfilename)) {
            print "<div  style='color:red;'>Can't copy file {$fielname} to " . HEURIST_FILES_DIR . "</div>";
            ob_flush();
            flush();
            // flush to screen
            return null;
        }
        $filename = $newfilename;
    }
    //returns new file id in dest database
    if ($externalFile) {
        $jsonData = json_encode(array('remoteURL' => $filename, 'ext' => $file['ulf_MimeExt'], 'params' => $file['ulf_Parameters'] ? $file['ulf_Parameters'] : null));
        $ret = register_external($jsonData, null, false);
    } else {
        $ret = register_file($filename, null, false);
    }
    if (intval($ret) > 0) {
        return $ret;
    } else {
        print "<div  style='color:red;'>Can't register file " . $filename . "</div>";
        ob_flush();
        flush();
        // flush to screen
        return null;
    }
}