/** * returns an array of detailType structured information for all detailTypes * detailTypes = {"groups" => {"groupIDToIndex":{detailTypeGroupID:index}, * index:{propName:val,...},...}, * "names":{dtyID:name,...}, * "rectypeUsage" => { dtyID => [rtyID,...], ...}, * 'usageCount' => {dtyID:nonzero-count,...}, * "typedefs":{"commonFieldNames":[defDetailTypes Column names], * "commonNamesToIndex":{"defDetailTypes columnName":index,...}, * dtyID:{"commonFields":[val,....]}, * ...}, * 'lookups' => {basetype=>displayName); * * @global int $dbID databse ID * @param boolean $useCachedData if true does a lookup for the detailtypes structure in cache * @return object information describing all the detailtypes defined in the database * @uses getDetailTypeColNames() * @uses __getColumnNameToIndex() * @uses __getRectypeStructureFieldColNames() * @uses getDetailTypeGroups() * @uses getDetailTypeUsageCount() * @uses getDetailTypeDefUsage() * @uses dbs_GetDtLookups() * @uses getCachedData() * @uses setCachedData() * * $dettypeids null means all, otherwise comma separated list of ids or list of field types (numeric,blocktext etc) * $imode 0 - only names and groupnames * 1 - only structure * 2 - full, both headers and structures * 3 - ids only */ function dbs_GetDetailTypes($system, $dettypeids = null, $imode) { $mysqli = $system->get_mysqli(); $dbID = $system->get_system('sys_dbRegisteredID'); /* ARTEM global $mysqli, $dbID; $cacheKey = DATABASE . ":AllDetailTypeInfo"; if ($useCachedData) { $dtStructs = getCachedData($cacheKey); if ($dtStructs) { return $dtStructs; } } */ $dtStructs = array(); if ($imode != 1) { $dtG = getDetailTypeGroups($mysqli); $dtStructs['groups'] = $dtG; $dtStructs['names'] = array(); } if ($imode > 0) { $dtStructs['typedefs'] = array('commonFieldNames' => getDetailTypeColNames(), 'fieldNamesToIndex' => __getColumnNameToIndex(getDetailTypeColNames())); $dtStructs['lookups'] = dbs_GetDtLookups(); } if (false && $imode == 2) { $dtStructs['rectypeUsage'] = getDetailTypeDefUsage($mysqli); $dtStructs['usageCount'] = getDetailTypeUsageCount($mysqli); } $where_exp = null; if ($dettypeids != null || $dettypeids != '' && $dettypeids != 'all') { if (!is_array($dettypeids)) { $dettypeids = array($dettypeids); } if ($dettypeids[0] != 'all') { //detect ID or TYPE if (is_int($dettypeids[0])) { $where_exp = ' dty_ID in (' . implode(',', $dettypeids) . ')'; } else { $where_exp = ' dty_Type in (\'' . implode("','", $dettypeids) . '\')'; } } } if ($imode == 3) { //ids only //$query = "select dty_ID from defDetailTypes"; if ($where_exp == null) { $where_exp = ''; } $res = mysql__select_list($mysqli, 'defDetailTypes', 'dty_ID', $where_exp); return $res; } else { $query = "select dtg_ID, dtg_Name, " . join(",", getDetailTypeColNames()); $query = preg_replace("/dty_ConceptID/", "", $query); if ($dbID) { //if(trm_OriginatingDBID,concat(cast(trm_OriginatingDBID as char(5)),'-',cast(trm_IDInOriginatingDB as char(5))),'null') as trm_ConceptID $query .= " if(dty_OriginatingDBID, concat(cast(dty_OriginatingDBID as char(5)),'-',cast(dty_IDInOriginatingDB as char(5))), concat('{$dbID}-',cast(dty_ID as char(5)))) as dty_ConceptID"; } else { $query .= " if(dty_OriginatingDBID, concat(cast(dty_OriginatingDBID as char(5)),'-',cast(dty_IDInOriginatingDB as char(5))), '') as dty_ConceptID"; } $query .= " from defDetailTypes left join defDetailTypeGroups on dtg_ID = dty_DetailTypeGroupID"; if ($where_exp != null) { $query = $query . ' where ' . $where_exp; } $query = $query . " order by dtg_Order, dtg_Name, dty_OrderInGroup, dty_Name"; } $res = $mysqli->query($query); //ARTEM $dtStructs['sortedNames'] = mysql__select_assoc('defDetailTypes', 'dty_Name', 'dty_ID', '1 order by dty_Name'); try { if (!$res) { error_log('FAILED QUERY: ' . $mysqli->error); //$query); error_log('Database: ' . HEURIST_DBNAME); } else { while ($row = $res->fetch_row()) { if ($imode != 1) { array_push($dtStructs['groups'][$dtG['groupIDToIndex'][$row[0]]]['allTypes'], $row[2]); if ($row[17]) { // dty_ShowInLists array_push($dtStructs['groups'][$dtG['groupIDToIndex'][$row[0]]]['showTypes'], $row[2]); } $dtStructs['names'][$row[2]] = $row[3]; } $dtStructs['typedefs'][$row[2]]['commonFields'] = array_slice($row, 2); } } } catch (Exception $e) { //trying to find veird error - missed trm_Modified column error_log('Message: ' . $e->getMessage()); error_log('QUERY: ' . $query); error_log('Database: ' . HEURIST_DBNAME); } //SPECIAL CASE for relation type #6 if ($imode > 0 && @$dtStructs['typedefs'][DT_RELATION_TYPE]) { $idx = $dtStructs['typedefs']['fieldNamesToIndex']['dty_JsonTermIDTree']; $dtStructs['typedefs'][DT_RELATION_TYPE]['commonFields'][$idx] = 0; $idx = $dtStructs['typedefs']['fieldNamesToIndex']['dty_TermIDTreeNonSelectableIDs']; $dtStructs['typedefs'][DT_RELATION_TYPE]['commonFields'][$idx] = ''; } //ARTEM setCachedData($cacheKey, $dtStructs); return $dtStructs; }
/** * Remove detail value for given set of records and detail type and values */ public function detailsDelete() { if (!$this->_validateParamsAndCounts()) { return false; } else { if (count(@$this->recIDs) == 0) { return $this->result_data; } } $dtyID = $this->data['dtyID']; $dtyName = @$this->data['dtyName'] ? "'" . $this->data['dtyName'] . "'" : "id:" . $this->data['dtyID']; $isDeleteAll = !array_key_exists("sVal", $this->data) || $this->data['sVal'] == ''; $mysqli = $this->system->get_mysqli(); $basetype = mysql__select_value($mysqli, 'select dty_Type from defDetailTypes where dty_ID = ' . $dtyID); switch ($basetype) { case "freetext": case "blocktext": case "enum": case "relationtype": case "float": case "integer": case "resource": case "date": $searchClause = $isDeleteAll ? '1' : "dtl_Value = \"" . $mysqli->real_escape_string($this->data['sVal']) . "\""; break; default: $this->system->addError(HEURIST_INVALID_REQUEST, "{$basetype} fields are not supported by deletion service"); return false; } //get array of required detail types per record type $rtyRequired = mysql__select_list($mysqli, "defRecStructure", "rst_RecTypeID", "rst_DetailTypeID = {$dtyID} and rst_RecTypeID in (" . implode(",", $this->rtyIDs) . ") and rst_RequirementType='required'"); $undefinedFieldsRecIDs = array(); //value not found $processedRecIDs = array(); //success $limittedRecIDs = array(); //it is npt possible to delete requried fields $sqlErrors = array(); $now = date('Y-m-d H:i:s'); $dtl = array('dtl_Modified' => $now); $rec_update = array('rec_ID' => 'to-be-filled', 'rec_Modified' => $now); $baseTag = "~delete field {$dtyName} {$now}"; foreach ($this->recIDs as $recID) { //get matching detail value for record if there is one $valuesToBeDeleted = mysql__select_list($mysqli, "recDetails", "dtl_ID", "dtl_RecID = {$recID} and dtl_DetailTypeID = {$dtyID} and {$searchClause}"); if ($valuesToBeDeleted == null && $mysqli->error) { $sqlErrors[$recID] = $mysqli->error; continue; } else { if ($valuesToBeDeleted == null || count($valuesToBeDeleted) == 0) { //not found array_push($undefinedFieldsRecIDs, $recID); continue; } } //validate if details can be deleted for required fields if (count($this->rtyIDs) > 1) { //get rectype for current record $rectype_ID = mysql__select_value($mysqli, 'select rec_RecTypeID from Records where rec_ID=' . $recID); } else { $rectype_ID = $this->rtyIDs[0]; } if (array_search($rectype_ID, $rtyRequired) !== FALSE) { //this is required field if (!$isDeleteAll) { //find total count $total_cnt = mysql__select_value($mysqli, "select count() from recDetails where " . " where dtl_RecID = {$recID} and dtl_DetailTypeID = {$dtyID}"); } if ($isDeleteAll || $total_cnt == count($valuesToBeDeleted)) { array_push($limittedRecIDs, $recID); continue; } } //delete the details $sql = 'delete from recDetails where dtl_ID in (' . implode(',', $valuesToBeDeleted) . ')'; if ($mysqli->query($sql) === TRUE) { array_push($processedRecIDs, $recID); //update record edit date $rec_update['rec_ID'] = $recID; $ret = mysql__insertupdate($mysqli, 'Records', 'rec', $rec_update); if (!is_numeric($ret)) { $sqlErrors[$recID] = 'Cannot update modify date. ' . $ret; } } else { $sqlErrors[$recID] = $mysqli->error; } } //for recors //assign special system tags $this->_assignTagsAndReport('processed', $processedRecIDs, $baseTag); $this->_assignTagsAndReport('undefined', $undefinedFieldsRecIDs, $baseTag); $this->_assignTagsAndReport('limitted', $limittedRecIDs, $baseTag); $this->_assignTagsAndReport('errors', $sqlErrors, $baseTag); return $this->result_data; }
}else{ //query = {"t":"25","f:154":"4799"}; $query = "t:25 sortby:f:94"; //f:154:4799 } */ //@todo all this stuff should be implemented on client side since header is not static content anymore // Put record types & counts in the table if ($system->is_inted()) { $res = $system->get_mysqli()->query($query); $stats = array(); while ($row = $res->fetch_assoc()) { // each loop is a complete table row if ($row["ord"] > 0) { if ($appcode > 0) { //detect app $list = mysql__select_list($system->get_mysqli(), 'recDetails', 'dtl_Value', 'dtl_recID=' . $row["id"] . ' and dtl_DetailTypeID=154'); //145 $classes = ''; $isNotFound = true; if (is_array($list)) { foreach ($list as $val) { if ($val == $appcode) { $isNotFound = false; break; } } } if ($isNotFound) { continue; } }