"
."Error: parameter $name is missing";
}
}
################################################################
# REWRITES $date in a standard format.
# Returns empty string or a error message.
function edit_std_date(&$date) {
global $conn;
$error = '';
if($date) {
@ $q = pg_exec($conn,
"SELECT '$date'::timestamp as date;"
);
if(!$q) {
$error = "edit_std_date(): Invalid date: $date ["
. pg_last_error($conn)
."]";
}
else {
$date = pg_result($q,0,'date');
}
}
return $error;
}
################################################################
# REWRITES $item_id in a standard format.
# $type may be either numeric or exact type name string
#
# Returns empty string or a error message.
# $id is not modified in case of a error.
function edit_std_id(&$id, $type_str) {
global $conn;
$error = '';
if($id != "") {
## ----------------
## Find type number and name
$res = get_type_info($type_str);
$error .= $res['error'];
if(!$error) {
$description = $res['description'];
$type = $res['type'];
## This checks format of the $id
$num = string_to_numeric($id, $type, $error);
}
if(!$error) {
$q = pg_exec($conn,
"SELECT sernum_first,sernum_last,iscustomid"
." FROM item_types"
." WHERE type=$type;"
);
if(!$q) {
$error .= "edit_std_id(): Can't pg_exec() for sernum range.";
}
elseif(pg_numrows($q) != 1) {
$error .= "edit_std_id(): unknown item type $type";
}
## ----------------
# Numeric value can be checked only
# when custom ids are not used.
if(pg_result($q,0,'iscustomid') == 'f') {
$sernum_first = pg_result($q,0,'sernum_first');
$sernum_last = pg_result($q,0,'sernum_last');
if($num < $sernum_first || $num > $sernum_last)
{
$error .= "edit_std_id(): "
."Serial number $num is outside valid "
."range($sernum_first, $sernum_last)"
." for $description.\n";
}
}
}
if(!$error) {
$id = numeric_to_string($num, $type, &$error);
}
}
return $error;
}
################################################################
# $type_str may be either numeric or exact type name string
#
# Returns array(error, type, description)
function get_type_info($type_str) {
global $conn;
$res = array(
'error' => '',
'type' => '',
'description' => ''
);
if($type_str) {
## ----------------
## Find type number and name
$condition = (is_numeric($type_str)) ?
"type='$type_str'"
: ("description='". addslashes($type_str) ."'")
;
$q = pg_exec( $conn,
"SELECT type,description FROM item_types"
." WHERE $condition;"
);
if(!$q) {
$res['error'] .= "get_type_info(): "
."Error in pg_exec() for type params.";
}
elseif(pg_numrows($q) != 1) {
$res['error'] .= "get_type_info(): "
."wrong number of rows for type params."
;
}
else {
$res['description'] = pg_result($q,0,'description');
$res['type'] = pg_result($q,0,'type');
}
}
return $res;
}
################################################################
# Detect a variable change and check validity of the change.
# Returns array with keys "error" and "diff"
# "error" contains a error message, if any.
# "diff" itself is an array with parameter and date names as keys,
# or an empty array if vars were not modified or if there is an error.
#
# Function queries database to check date format.
#
function check_change($parnames, $datename, &$vararray) {
global $conn;
$date = &$vararray["$datename"];
$old_date = &$vararray["old_$datename"];
$res = array (
'error' => '',
'diff' => array()
);
## ================================================================
## Rewrite date in standard format
$res['error'] .= edit_std_date(&$date);
## ================================================================
$changed = 0;
reset($parnames);
while(list($key, $parname) = each($parnames)) {
if($vararray["$parname"] != $vararray["old_$parname"]) {
$changed = 1;
}
}
## ================================================================
if($changed && ($old_date == $date)) {
$res['error'] .= "check_change(): "
."You've done some modifications, "
."but haven't change the date.\n";
}
## ================================================================
if($changed || ($old_date != $date))
{
if(! $date ) {
$res['error'] .= "check_change(): Required date field missing";
}
reset($parnames);
while(list($key, $parname) = each($parnames)) {
$res['diff']["$parname"] = $vararray["$parname"];
$res['diff']["old_$parname"] = $vararray["old_$parname"];
}
$res['diff']["$datename"] = $date;
$res['diff']["old_$datename"] = $old_date;
}
return $res;
}
################################################################
# Detect a variable change and check validity of the change.
# Returns array with keys "error" and "diff"
# "error" contains a error message, if any.
# "diff" itself is an array with four abovementioned vars as keys,
# or an empty array if vars were not modified or if there is a error.
#
# Function queries database to check date format.
#
function check_change4($name, &$vararray) {
global $conn;
$val = &$vararray["$name"];
$old_val = &$vararray["old_$name"];
$date = &$vararray["$name" . "_date"];
$old_date = &$vararray["old_$name" . "_date"];
$res = array (
'error' => '',
'diff' => array()
);
## ================================================================
## Rewrite date in standard format
$res['error'] .= edit_std_date(&$date);
if($old_date) {
$res['error'] .= edit_std_date(&$old_date);
}
## ================================================================
if(($old_val != $val) && ($old_date == $date)) {
$res['error'] .= "check_change4(): "
."You've done some modifications, "
."but haven't change the date.\n";
}
## ================================================================
if(($old_val != $val) || ($old_date != $date))
{
if(! $date ) {
$res['error'] = "check_change4(): Required date field missing";
}
$res['diff'] = array (
("$name") => $val,
("old_$name") => $old_val,
("$name" . "_date") => $date,
("old_$name" . "_date") => $old_date
);
}
return $res;
}
################################################################
function change4_str( $description, $name,
&$errflag, &$vararray)
{
$res = check_change4($name, $vararray);
if($res['error']) {
$errflag = 1;
}
## The only kind of detected error is an error in date
$datestring = $errflag ?
"$res[error]"
: ($vararray["$name" . "_date"])
;
return $res['diff'] ?
"
"
."$description | "
."". $vararray["old_$name"] ." | "
."$vararray[$name] | "
."$datestring | "
."
\n"
:
""
;
}
################################################################
# Detect a variable change and check validity of the change.
#
# A step is either "install" or "remove" operation
# with all necessary parameters: (base,point,part,date)
#
function check_connection_change( $base_type_name, $base_id_name,
$point_name,
$part_type_name, $part_id_name,
$date_name, &$vararray,
$item_point_name = '')
{
global $conn;
$base_type = &$vararray[$base_type_name];
$base_id = &$vararray[$base_id_name];
$point = &$vararray[$point_name];
$part_type = &$vararray[$part_type_name];
$part_id = &$vararray[$part_id_name];
$date = &$vararray[$date_name];
$item_point = $item_point_name ? $vararray[$item_point_name] : 0;
$old_base_type = &$vararray['old_' . $base_type_name];
$old_base_id = &$vararray['old_' . $base_id_name];
$old_point = &$vararray['old_' . $point_name];
$old_part_type = &$vararray['old_' . $part_type_name];
$old_part_id = &$vararray['old_' . $part_id_name];
$old_date = &$vararray['old_' . $date_name];
$old_item_point = $item_point_name ? $vararray['old_' . $item_point_name] : 0;
$res = array (
'error' => '',
'steps'=> array()
);
## ================================================================
## Rewrite vars in standard format
$res['error'] .= edit_std_date(&$date);
$res['error'] .= edit_std_date(&$old_date);
$res['error'] .= edit_std_id(&$base_id, $base_type);
$res['error'] .= edit_std_id(&$old_base_id, $old_base_type);
$res['error'] .= edit_std_id(&$part_id, $part_type);
$res['error'] .= edit_std_id(&$old_part_id, $old_part_type);
## ----------------
$tt = get_type_info($old_base_type);
$res['error'] .= $tt['error'];
$old_base_type = $tt['type'];
$old_base_description = $tt['description'];
$tt = get_type_info($old_part_type);
$res['error'] .= $tt['error'];
$old_part_type = $tt['type'];
$old_part_description = $tt['description'];
$tt = get_type_info($base_type);
$res['error'] .= $tt['error'];
$base_type = $tt['type'];
$base_description = $tt['description'];
$tt = get_type_info($part_type);
$res['error'] .= $tt['error'];
$part_type = $tt['type'];
$part_description = $tt['description'];
## ================================================================
if((($base_type != $old_base_type ) ||
($base_id != $old_base_id ) ||
($point != $old_point ) ||
($part_type != $old_part_type ) ||
($item_point != $old_item_point) ||
($part_id != $old_part_id )) &&
($date == $old_date ) )
{
$res['error'] .= "check_connection_change(): "
."You've done some modifications, "
."but haven't change the date.\n";
}
## ================================================================
if( ($base_type != $old_base_type ) ||
($base_id != $old_base_id ) ||
($point != $old_point ) ||
($part_type != $old_part_type ) ||
($item_point != $old_item_point) ||
($part_id != $old_part_id )
########## || ($date != $old_date )
)
{
$request_complete = 0;
if( ($old_base_id != "")
&& ($old_part_id != "")
&& ($old_point != "")
)
{
$q = pg_exec( $conn,
"SELECT name"
." FROM base_point_names"
." WHERE base_type = $old_base_type"
." AND connected_at = $old_point;"
);
if(!$q) {
$res['error'] .= "check_connection_change(): "
."Error getting point name.\n";
}
$point_name = pg_result($q, 0, 0);
$res['steps'][] = array(
'action' => 'remove',
'base_type' => $old_base_type,
'base_description' => $old_base_description,
'base_id' => $old_base_id,
'point' => $old_point,
'point_name' => $point_name,
'part_type' => $old_part_type,
'part_description' => $old_part_description,
'item_point' => $old_item_point,
'part_id' => $old_part_id,
'date' => $date ## NOT old
);
$request_complete = 1;
}
if( ($base_id != "")
&& ($part_id != "")
&& ($point != "")
)
{
$q = pg_exec( $conn,
"SELECT name"
." FROM base_point_names"
." WHERE base_type = $base_type"
." AND connected_at = $point;"
);
if(!$q) {
$res['error'] .= "check_connection_change(): "
."Error getting point name.\n";
}
$point_name = pg_result($q, 0, 0);
$res['steps'][] = array(
'action' => 'install',
'base_type' => $base_type,
'base_description' => $base_description,
'base_id' => $base_id,
'point' => $point,
'point_name' => $point_name,
'part_type' => $part_type,
'part_description' => $part_description,
'item_point' => $item_point,
'part_id' => $part_id,
'date' => $date
);
$request_complete = 1;
}
if(!$request_complete) {
$res['error'] .= "check_connection_change(): "
."Request to install/remove an item"
." is not complete:\n"
."Args:\n"
."base_type_name, base_id_name,\n"
."point_name, \n"
."part_type_name, part_id_name, \n"
."date_name, item_point_name\n"
." = \n"
."$base_type_name, $base_id_name,\n"
."$point_name, \n"
."$part_type_name, $part_id_name, \n"
."$date_name, $item_point_name\n"
."(base_id, point, part_id, item_point)="
."($base_id, $point, $part_id, $item_point)\n"
."(old_base_id, old_point, old_part_id, old_item_point)="
."($old_base_id, $old_point, $old_part_id, $old_item_point)\n"
;
}
elseif(!$date) {
$res['error'] .= "check_connection_change(): "
."Required date field missing.";
}
}
## ================================================================
return $res;
}
################################################################
# Should be called inside a transaction opened with start_transaction()
# Inserts a record into table "connections"
# $step should be an array in format as returned by check_connection_change()
#
# Returns emtpy string or error message
function edit_set_connection($step) {
global $conn;
$err = '';
if($step['action'] == 'install') {
$part_sernum = make_sernum($conn, $step['part_id'],
$step['part_type']);
$base_sernum = make_sernum($conn, $step['base_id'],
$step['base_type']);
if(!$err) {
$q = pg_exec( $conn,
"INSERT INTO connections "
." (tn,base_id,connected_at,item_id,item_point,workdate,set)"
." VALUES ("
."currval('tn'),"
."'$base_sernum','$step[point]',"
."'$part_sernum','$step[item_point]',"
."'$step[date]','t'"
.");"
);
if(!$q) {
$err .= "edit_set_connection(): error installing part.";
}
else {
if(pg_cmdTuples($q) != 1) {
$err .= "edit_set_connection(): wrong number of"
." tuples inserted: "
. pg_cmdTuples($q)
." instead of 1.";
}
}
}
}
## ================================================================
elseif($step['action'] == 'remove') {
## Check is that the connection to be unset does exist.
$base_sernum = find_sernum($conn, $step['base_id'],
$step['base_type']);
$part_sernum = find_sernum($conn, $step['part_id'],
$step['part_type']);
## ================
## Write to the database
if(!$err) {
$q = pg_exec( $conn,
"INSERT INTO connections"
." (tn,base_id,connected_at,item_id,item_point,workdate,set)"
." VALUES "
." (currval('tn'),"
." '$base_sernum','$step[point]',"
." '$part_sernum','$step[item_point]',"
." '$step[date]','f');"
);
if(!$q) {
$err .= "edit_set_connection(): error removing part.";
}
else {
if(pg_cmdTuples($q) != 1) {
$err .= "edit_set_connection(): wrong number of"
." tuples affected in removing: "
. pg_cmdTuples($q)
." instead of 1.";
}
}
}
}
## ================================================================
else {
$err .= "edit_set_connection(): unknown action '$step[action]'";
}
return $err;
}
################################################################
# Should be called inside a transaction opened with start_transaction()
# Inserts an entry into $item_table where $item_table
# inherits(item_record) and has the only additional field $field_name
# $list_table has ("$field_name" int4, description text) columns
# $field_name set to the value with $choice matching description.
#
# Returns empty string on success, error message otherwise.
# Uses global $conn
function edit_set_selected( $sernum, $choice, $date,
$item_table, $list_table,
$field_name)
{
global $conn;
$err = '';
$q = pg_exec($conn,
"INSERT INTO \"$item_table\""
." (tn,sernum,workdate,\"$field_name\")"
." SELECT currval('tn'),$sernum,"
." '$date',\"$field_name\""
." FROM \"$list_table\""
." WHERE description='$choice';"
);
if(!$q) {
$err .= "edit_set_selected():"
." Error inserting \"$field_name\" into $item_table.";
}
elseif(pg_cmdTuples($q) != 1) {
$err .= "edit_set_selected(): Error: "
."Wrong number of tuples affected: "
. pg_cmdTuples($q)
." instead of 1.";
}
return $err;
}
################################################################
# Should be called inside a transaction opened with start_transaction()
# Inserts an entry into $item_table where $item_table
# inherits(item_record)
#
# $values is an array of the form ($field1_name => $value1, ...)
#
# Returns empty string on success, error message otherwise.
# Uses global $conn
function edit_set_values( $sernum, $item_table, $date, $values)
{
global $conn;
$err = '';
$field_string = '';
$value_string = '';
reset($values);
while(list($key, $value) = each($values)) {
$field_string .= ',"' . addslashes($key) . '"';
$value_string .= ",'" . addslashes($value) . "'";
}
$q = pg_exec($conn,
"INSERT INTO \"$item_table\""
." (tn,sernum,workdate $field_string)"
." VALUES( currval('tn'), $sernum,'$date'"
."$value_string);"
);
if(!$q) {
$err .= "edit_set_value():"
." Error inserting \"$field_string\" into $item_table.";
}
elseif(pg_cmdTuples($q) != 1) {
$err .= "edit_set_value(): Error: "
."Wrong number of tuples affected: "
. pg_cmdTuples($q)
." instead of 1.";
}
return $err;
}
################################################################
# $field_names is an array of field names to use in query.
# It's allowed to use a scalar instead of the array if a single
# field is to be queried.
#
# $item_table should inherit(item_record) and have all the fields.
#
# Returns array with "date", "error" and requested field name keys.
# Error is either an empty string, or an error message.
#
#
# Uses global $conn
function edit_get_value( $sernum, $item_table, $field_names)
{
global $conn;
if(!is_array($field_names)) {
$field_names = array("$field_names");
}
$res = array( 'error' => '',
'date' => ''
);
$field_string = '';
reset($field_names);
while(list($key, $value) = each($field_names)) {
$field_string .= '"' . addslashes($value) . '",';
$res[$value] = '';
}
if($sernum) {
$q = pg_exec( $conn,
# the comma is in $field_string
"SELECT $field_string workdate"
." FROM \"$item_table\""
." WHERE sernum=$sernum"
." ORDER BY tn DESC LIMIT 1;"
);
if(!$q) {
$res['error'] .= "edit_get_value(): "
."Error selecting \"$field_name\""
." from $item_table.";
}
elseif(pg_numrows($q) == 1) {
$res['date'] = pg_result($q,0,'workdate');
reset($field_names);
while(list($key, $value) = each($field_names)) {
$res[$value] = pg_result($q,0,$value);
}
}
}
return $res;
}
################################################################
# Returns array with "$field_name", "date", "options"
# and "error" keys.
# Error is either an empty string, or an error message.
# "options" is an html string to be used between
#
# $item_table inherits(item_record) and has a field $field_name
# $list_table has ("$field_name" int4, description text) columns
#
# Uses global $conn
function edit_get_selected( $sernum, $item_table,
$list_table, $field_name)
{
global $conn;
$res = array( 'error' => '',
"$field_name" => '',
'date' => '',
'options' => ''
);
## ----------------
## Find current value, if any
if($sernum) {
$q = pg_exec($conn,
"SELECT b.description,a.workdate"
." FROM \"$item_table\" a,"
." \"$list_table\" b"
." WHERE a.\"$field_name\"=b.\"$field_name\""
." AND a.sernum='$sernum'"
." ORDER BY a.tn DESC LIMIT 1;"
);
if(!$q) {
$res['error'] .= "edit_get_selected(): "
."Error selecting \"$field_name\""
;
}
else {
if(pg_numrows($q) == 1) {
$res[$field_name] = pg_result($q,0,'description');
$res['date'] = pg_result($q,0,'workdate');
}
}
}
## ----------------
## Extract list of all possible choices
$q = pg_exec( $conn,
"SELECT description FROM \"$list_table\""
." ORDER BY \"$field_name\";"
);
if(!$q) {
$res['error'] .= "edit_get_selected(): "
."Error in pg_exec() for "
."\"$list_table\" options.";
}
else {
$numrows = pg_numrows($q);
$res['options'] = '';
for($row=0; $row<$numrows; $row++) {
$opt = pg_result($q, $row, 'description');
$sel = ($opt == $res[$field_name]) ? " selected" : "";
$res['options'] .= "