function rollback( $db_conn ) { GLOBAL $msg_log; message_log_append( $msg_log, "ROLLBACK" ); return( mysql_query( "ROLLBACK", $db_conn ) ); }
function insert_sql_data( $db_conn, $p_campaigns, $p_headers, $p_details ) // insert the header and detail data into the file // with appropriate safeguards to ensure full // completion or rollback of the transaction. { GLOBAL $msg_log; $success = TRUE; // Wrap all this in a transaction // First, turn off autocommit $qry = "set autocommit=0"; //pre_echo( $qry ); $success = mysql_query( $qry, $db_conn ); // Second, take care of all ALTER TABLE queries. Due to a (documented) // glitch in MySQL, these commands force a transaction to commit, // which sucks. if ($success) { // Create the temp_header table $qry = "CREATE TEMPORARY TABLE temp_header LIKE contract_header"; //pre_echo( $qry ); $success = mysql_query( $qry, $db_conn ); if (!$success) { message_log_append( $msg_log, mysql_error( $db_conn ), MSG_LOG_ERROR ); } } if ($success) { // Create the temp_detail table $qry = "CREATE TEMPORARY TABLE temp_detail LIKE contract_detail"; //pre_echo( $qry ); $success = mysql_query( $qry, $db_conn ); if (!$success) { message_log_append( $msg_log, mysql_error( $db_conn ), MSG_LOG_ERROR ); } } if ($success) { // Delete the Seq field from table temp_header $qry = "ALTER TABLE temp_header DROP COLUMN Seq"; //pre_echo( $qry ); $success = mysql_query( $qry, $db_conn ); if (!$success) { message_log_append( $msg_log, mysql_error( $db_conn ), MSG_LOG_ERROR ); } } if ($success) { // Delete the Line column from table temp_detail $qry = "ALTER TABLE temp_detail DROP COLUMN Line"; //pre_echo( $qry ); $success = mysql_query( $qry, $db_conn ); if (!$success) { message_log_append( $msg_log, mysql_error( $db_conn ), MSG_LOG_ERROR ); } } // loop through the campaigns, headers, and details to insert the // data into the SQL database. Keep solid track of all error // results so that we can ROLLBACK on any error. if ($success) { //echo "<pre>"; //var_dump( $p_campaigns ); echo "</pre><br>"; $success = begin( $db_conn ); if (!$success) { message_log_append( $msg_log, "Error in START TRANSACTION: " . mysql_error( $db_conn ), MSG_LOG_ERROR ); } } // do the work here, and keep track of $success // If we need to create a new agency record, do that here. $new_agency = FALSE; if ($success && is_null( $p_campaigns[0][ 'Agency Record' ])) { $agent_name = $p_campaigns[0][ 'Agency Name' ]; $rate = DEFAULT_AGENCY_RATE / 10; if ($success = agency_insert( $db_conn, $agent_name, $rate, $aindex )) { $p_campaigns[0][ 'Agency Record' ] = agency_record( $agent_name, OPERATOR_NAME ); $success = !is_null( $p_campaigns[0][ 'Agency Record' ]); } // if agency_insert if ($success) { $new_agency = TRUE; message_log_append( $msg_log, "Agency created: " . "Seq = $aindex, Name = '$agent_name'", MSG_LOG_WARNING ); } else { message_log_append( $msg_log, "Error while creating " . "Agency '$agent_name': " . mysql_error( $db_conn ), MSG_LOG_ERROR ); } } // if null agency record // If we need to create a new customer record, do that here. $new_customer = FALSE; if ($success && is_null( $p_campaigns[0][ 'Customer Record' ])) { $cust_name = $p_campaigns[0][ 'Customer Name' ]; $rate = DEFAULT_CUST_DISCOUNT; if ($success = customer_insert( $db_conn, $cust_name, $rate, $cindex )) { $p_campaigns[0][ 'Customer Record' ] = cust_record( $cust_name, OPERATOR_NAME ); $success = !is_null( $p_campaigns[0][ 'Customer Record' ]); } // if customer_insert if ($success) { $new_customer = TRUE; message_log_append( $msg_log, "Customer created: " . "Seq = $cindex, Name = '$cust_name'", MSG_LOG_WARNING ); } else { message_log_append( $msg_log, "Error while creating " . "Customer '$cust_name' " . mysql_error( $db_conn ), MSG_LOG_ERROR ); } } // if null customer record if ($success) { // build the list of header fields, in order with 'quote required' flag // [n][0] is field name, [n][1] is boolean T=quote required, F=not $hdr_flds = build_header_field_array(); // A SQL INSERT statement lead-in $hdr_sql = "INSERT INTO temp_header ( "; $hdr_sql .= fld_list( $hdr_flds ) . ") VALUES\n"; // build the list of detail fields, in order with 'quote required' flag // [n][0] is field name, [n][1] is boolean T=quote required, F=not $det_flds = build_detail_field_array(); // A SQL INSERT statement lead-in $det_sql = "INSERT INTO temp_detail ( "; $det_sql .= fld_list( $det_flds ) . ") VALUES "; // Here we go. We'll loop through each contract header record, // and its accompanying detail records. $n_inserted = 0; while ($success && (list( $key ) = each( $p_headers ))) { if (count( $p_details[ $key ] ) > 0) { // If we created a new agency or customer above, update // the respective header fields. if ($new_customer) { $p_headers[ $key ][ 'CIndex' ] = $cindex; $p_headers[ $key ][ 'Discount' ] = $p_campaigns[0][ 'Customer Record' ][ 'Discount' ]; } if ($new_agency) { $p_headers[ $key ][ 'AIndex' ] = $aindex; $p_headers[ $key ][ 'AgencyComm' ] = $p_campaigns[0][ 'Agency Record' ][ 'Rate' ]; } $row = data_values( $hdr_flds, $p_headers[ $key ] ); $sql_header = $hdr_sql; // INSERT INTO ... VALUES $sql_header .= "(" . $row . ");"; $rows = ""; foreach ($p_details[ $key ] as $line) { $rows .= ",\n( " . data_values( $det_flds, $line ) . " )"; } $rows = substr( $rows, 1 ); // remove comma-newline $sql_detail = $det_sql; // INSERT INTO ... VALUES $sql_detail .= $rows; if ($success = do_insert( $db_conn, $sql_header, $sql_detail )) { $n_inserted++; } } // if detail count > 0 } // while success and each key } // if success if ($success) { $success = commit( $db_conn ); if ($success) { message_log_append( $msg_log, "$n_inserted contract" . ($n_inserted == 1 ? '' : 's') . " imported" ); } else { message_log_append( $msg_log, "Error in COMMIT TRANSACTION: " . mysql_error( $db_conn ), MSG_LOG_ERROR ); if (!rollback( $db_conn )) { message_log_append( $msg_log, "Error in ROLLBACK TRANSACTION: " . mysql_error( $db_conn ), MSG_LOG_ERROR ); } } } else { if (!rollback( $db_conn )) { message_log_append( $msg_log, "Error in ROLLBACK TRANSACTION: " . mysql_error( $db_conn ), MSG_LOG_ERROR ); } } // if success return( $success ); } // insert_sql_data
function parse_xml( $xmlfile, // input file to parse &$camp_header, // campaign output array returned to caller &$cont_header, // header output array returned to caller &$cont_detail // detail output array returned to caller ) // return TRUE if no errors, else FALSE { GLOBAL $msg_log; //GLOBAL $DEBUG; //if ($DEBUG) //echo "<pre>"; //echo "0: begin parse_xml\N"; $n_contract = 0; // index of contracts parsed $camp_header = array(); // array, but limited to one element, [0] $cont_header = array(); // $cont_header[N] is header for index N $cont_detail = array(); // $cont_detail[N] is detail array for index N $success = TRUE; //echo "0: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); if ($success) { //if ($DEBUG) echo "loading XML\n"; $success = ($xml = simplexml_load_file( $xmlfile )); if (!$success) echo "Can't load XML file.\n"; } //echo "1: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); if ($success) { $success = ($xml->document->documentType == 'Order'); if (!$success) echo "XML file is the wrong documentType.\n"; } //echo "2: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); if ($success) { $success = (count_xml_elements( $xml, '/adx/campaign' ) == 1); if (!$success) echo "Invalid number of campaigns in XML file.\n"; } // if //echo "3: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); if ($success) { $success = ($campaign = $xml->xpath( '/adx/campaign' )); if ($success) { //if ($DEBUG) echo "parsing campaign\n"; $success = parse_campaign( $campaign[0], $camp_header[0] ); //if ($DEBUG) { //echo "done parsing campaign, ID='" . $camp_header[0]['CampKeyID'] . "'<br>\n"; ////echo "<pre>"; ////var_dump( $camp_header[0] ); ////echo "</pre>"; //} if (!$success) { message_log_append( $msg_log, "Can't parse campaign from XML file", MSG_LOG_ERROR ); } // if } else message_log_append( $msg_log, "Can't locate 'campaign' node in XML file", MSG_LOG_ERROR ); } // if //echo "4: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); if ($success) { $sys_ords = $campaign[0]->xpath('/adx/campaign/order/systemOrder'); $n_sys_ord = 0; while ($success && isset( $sys_ords[ $n_sys_ord ] ) && !is_null( $sys_ords[ $n_sys_ord ] )) { set_time_limit( 20 ); // don't let the 30-second PHP timeout kill us //echo "4a: n_sys_ord = $n_sys_ord\n"; if ($n_contract < MAX_CONTRACTS) { //echo "4b: n_contract = $n_contract\n"; $one_header = array(); $one_detail = array(); $one_copy = array(); //if ($DEBUG) //echo "4c: parse_contract_header\n"; $success = parse_contract_header( $campaign[ 0 ], // XML object $sys_ords[ $n_sys_ord ], // XML object $camp_header[ 0 ], // array $one_header // array ); if ($success) //echo "4d: parse_contract_detail\n"; //if ($DEBUG) echo "parsing detail $contract_seq\n"; $success = parse_contract_detail( $campaign[0], // XML object $sys_ords[ $n_sys_ord ], // XML object $one_detail // array ); // if ($success) // $success = parse_contract_copy( // $campaign[0], // XML object // $sys_ords[ $n_sys_ord ], // XML object // $one_copy // array // ); if ($success) { //echo "4e: success\n"; //if ($DEBUG) { echo "one_detail: "; var_dump( $one_detail ); } foreach ($one_header['Site Records'] as $site_record) { $one_header['Site Records'] = array( $site_record ); $one_header['SiteName'] = $site_record['SiteName']; $contract_seq = $n_contract + 1; $cont_header[ $contract_seq ] = $one_header; $cont_detail[ $contract_seq ] = $one_detail; $cont_copy[ $contract_seq ] = $one_copy; $n_contract++; } // foreach site_record } $n_sys_ord++; } else { //echo "4z: too many contracts\n"; $success = FALSE; message_log_append( $msg_log, "XML file contains too many contracts", MSG_LOG_ERROR ); } // if } // while //echo "5: n_sys_ord = $n_sys_ord\n"; //echo "5: success = " . ($success ? "TRUE\n" : "FALSE\n" ); if (!$success) message_log_append( $msg_log, "Error while parsing XML file", MSG_LOG_ERROR ); } // if //echo "6: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); if ($success) { //if ($DEBUG) echo "$n_contract contract" . ($n_contract == 1 ? '' : 's') . " parsed successfully.\n"; //if ($DEBUG) echo "cont_header: "; //if ($DEBUG) var_dump( $cont_header ); //if ($DEBUG) echo "detail: "; //if ($DEBUG) var_dump( $cont_detail ); } // if //echo "6: " . ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); //echo ($success ? "parse_xml TRUE\n" : "parse_xml FALSE\n" ); //if ($DEBUG) //echo "</pre>\n"; return( $success ); } // parse_xml
function process_state( $ps_state ) //////////////////////////////////////////// // // A basic state machine. // // Given the $ps_state value passed, perform // the action dictated by that state. // //////////////////////////////////////////// { GLOBAL $argv; GLOBAL $msg_log; GLOBAL $db_host, $db_user, $db_pwd, $db_name; GLOBAL $DEBUG; $done = FALSE; // $cont_key is an integer 1 .. N of the contract number // we'll display. It indexes the arrays $headers and $details $cont_key = isset( $_SESSION[ 'cont_key' ] ) ? $_SESSION[ 'cont_key' ] : NULL; $campaigns = isset( $_SESSION[ 'campaigns' ] ) ? $_SESSION[ 'campaigns' ] : NULL; $headers = isset( $_SESSION[ 'headers' ] ) ? $_SESSION[ 'headers' ] : NULL; $details = isset( $_SESSION[ 'details' ] ) ? $_SESSION[ 'details' ] : NULL; // loop until we reach a state where the user (web client) // must perform an action to determine what the next state // will be. output_style_header(); do { message_log_reset( $msg_log ); if ($DEBUG) { message_log_append( $msg_log, "database name is $db_name\n" ); } if ($DEBUG) { message_log_append( $msg_log, "state is $ps_state\n" ); } switch (TRUE) { ///////////////////////////////// // // Initial state is BEGIN // ///////////////////////////////// case ($ps_state == 'BEGIN'): // Clear all keys in array $_SESSION foreach (array_keys( $_SESSION ) as $sess_key) { unset( $_SESSION[ $sess_key ] ); } // foreach // Proceed to a prompting state next_state( 'PROMPT_FOR_XML_INPUT' ); break; ///////////////////////////////// // // Prompt the user to provide an // XML file. // ///////////////////////////////// case ($ps_state == 'PROMPT_FOR_XML_INPUT'): // We are ready to prompt for an input file if (CLI) { ; // In CLI mode, the input file name will be on the command line. } else { prompt_for_xml_input(); } // The next step is to check the XML file for basic sanity checks next_state( 'CHECK_XML_FILENAME' ); // But first we have to wait for the web client to upload the file $done = TRUE; if (CLI) { $done = FALSE; } break; ///////////////////////////////// // // Do some basic checking on the // XML file the user provided. // ///////////////////////////////// case ($ps_state == 'CHECK_XML_FILENAME'): $input_nam = 'xmlfile'; // per the POST form $filnam = isset( $_FILES[ $input_nam ] ) ? $_FILES[ $input_nam ][ 'name' ] : NULL; // The full path to where the file was uploaded on the server $filtmp = isset( $_FILES[ $input_nam ] ) ? $_FILES[ $input_nam ][ 'tmp_name' ] : NULL; if (is_null( $filnam ) || is_null( $filtmp ) || (strlen( $filnam ) == 0) || (strlen( $filtmp ) == 0)) { next_state( 'BEGIN' ); } else { next_state( 'CHECK_XML_UPLOAD' ); } break; case ($ps_state == 'CHECK_XML_UPLOAD'): if (CLI) { $filtmp = $argv[1]; echo "input file is $filtmp\n"; } // The size of the file in bytes $filsiz = $_FILES[ $input_nam ][ 'size' ]; // The error code of the upload process $filerr = $_FILES[ $input_nam ][ 'error' ]; if (CLI || $filerr == UPLOAD_ERR_OK) { next_state( 'PARSE_XML_UPLOAD' ); } else { message_log_append( $msg_log, "Upload error $filerr", MSG_LOG_ERROR ); $done = TRUE; next_state( 'BEGIN' ); // start over } break; ///////////////////////////////// // // Do a full parsing of the // XML file the user provided. // ///////////////////////////////// case ($ps_state == 'PARSE_XML_UPLOAD'): open_mysql(); // What is the path portion of the $filtmp filename? $_SESSION[ 'xmlfile' ] = $filtmp; if ($DEBUG) { echo "calling parse_xml<br>\n"; echo "parsing file: $filtmp<br>\n"; } // Set state to start over, in case we fail before parse_xml // returns. next_state( 'BEGIN' ); // parse the XML file, returning an array of contract headers, // and an array of arrays of detail lines. First-order indices of // headers and details arrays will be integers starting from 1. if (parse_xml( $filtmp, $campaigns, $headers, $details )) { next_state( 'VERIFY_CAMPAIGN' ); } else { message_log_append( $msg_log, "XML order parsing failed", MSG_LOG_ERROR ); unset( $_SESSION[ 'campaigns' ] ); unset( $_SESSION[ 'headers' ] ); unset( $_SESSION[ 'details' ] ); next_state( 'TRY_AGAIN' ); } break; ///////////////////////////////// // // Verify some basic integrity // checks on the data, and create // human-readable log messages for // problems that are identified. // ///////////////////////////////// case ($ps_state == 'RE-VERIFY_CAMPAIGN'): // unset all header row MSG_LOG values foreach (array_keys( $headers ) as $key) { unset( $headers[ $key ][ 'MSG_LOG' ] ); } // unset all detail line MSG_LOG values foreach (array_keys( $details ) as $dkey) { foreach (array_keys( $details[ $dkey ] ) as $ln) { unset( $details[ $dkey ][ $ln ][ 'MSG_LOG' ] ); } } // and fall through to VERIFY_CAMPAIGN: case ($ps_state == 'VERIFY_CAMPAIGN'): verify_campaign( $campaigns, $headers, $details ); next_state( 'BEGIN' ); // as precaution //echo "calling verify_all_contracts<br>"; if (verify_all_contracts( $campaigns, $headers, $details )) { //echo "vac succeeded<br>"; } else { //echo "vac failed<br>"; } next_state( ($ps_state == 'VERIFY_CAMPAIGN') ? 'DISPLAY_CAMPAIGN' : 'DISPLAY_CONTRACT' ); break; case ($ps_state == 'DISPLAY_CAMPAIGN'): unset( $cont_key ); // contract array key next_state( 'DISPLAY_CONTRACT' ); break; case ($ps_state == 'DISPLAY_CONTRACT'): //echo "$ps_state<br>"; if (is_null( $campaigns ) || is_null( $headers ) || is_null( $details )) { next_state( 'BEGIN' ); } else { if (!isset( $cont_key ) || is_null( $cont_key )) { $keys = array_keys( $headers ); $cont_key = $keys[0]; } // if if (is_null( $cont_key )) { next_state( 'BEGIN' ); } else { echo html_campaign( $campaigns ); echo nav_buttons( array_keys( $headers ), TRUE, $headers, $cont_key ); echo html_order( $headers[$cont_key], $cont_key ); echo html_detail( $details[$cont_key], $cont_key ); // set a safe next state. form_handler ought to override, unless error. next_state( 'BEGIN' ); $done = TRUE; } //if } // if break; case ($ps_state == 'DISPLAY_NEXT'): $keys = array_keys( $headers ); $cont_key = next_cont_key( $cont_key, $keys ); // we might someday use a better state than BEGIN here. A NULL // return from next_cont_key would mean that no contracts remain. next_state( is_null( $cont_key ) ? 'BEGIN' : 'DISPLAY_CONTRACT' ); break; case ($ps_state == 'DISPLAY_PREV'): $keys = array_keys( $headers ); $cont_key = prev_cont_key( $cont_key, $keys ); next_state( is_null( $cont_key ) ? 'BEGIN' : 'DISPLAY_CONTRACT' ); break; ///////////////////////////////// // // Push SQL file out to // the web client for download. // ///////////////////////////////// case ($ps_state == 'PUSH_SQL_FILE'): next_state( 'BEGIN' ); if (CLI) { echo "SQL output is in file $sql_file\n"; } else { header( 'Content-type: application/force-download' ); header( 'Content-Transfer-Encoding: Binary' ); header( 'Content-length: ' . filesize( $sql_file ) ); header( 'Content-disposition: attachment; filename="' . basename( $sql_file ) . '"' ); readfile( $sql_file ); unlink( $sql_file ); // delete } $done = TRUE; break; ///////////////////////////////// // // Connect to the SQL server and // move the data into the database. // ///////////////////////////////// case ($ps_state == 'IMPORT'): next_state( 'BEGIN' ); open_mysql(); insert_sql( $campaigns, $headers, $details ); echo message_log_format( $msg_log ); message_log_reset( $msg_log ); break; ///////////////////////////////// // // Delete a LineID from a contract // ///////////////////////////////// case ($ps_state == 'DELETE_LINE'): $lineID = $_SESSION[ 'LineID' ]; // XML LineID number //message_log_append( $msg_log, 'You requested to delete LineID ' . $lineID . ' from contract key ' . $cont_key ); // Deleting detail lines will change the header spot and value totals. // delete_detail_lineid is responsible for telling us how many spots // were deleted, and what their total value was. $spots = 0; $value = 0; $details[ $cont_key ] = delete_detail_lineid( $details[ $cont_key ], $lineID, $spots, $value ); // subtract deleted spots and value from header 'detail_*' totals $headers[ $cont_key ][ 'detail_spots' ] -= $spots; $v = $headers[ $cont_key ][ 'detail_cost' ]; $v = bcsub( $v, $value, 2 ); $headers[ $cont_key ][ 'detail_cost' ] = $v; // subtract deleted spots and value from header 'total_*' totals $headers[ $cont_key ][ 'total_spots' ] -= $spots; $v = $headers[ $cont_key ][ 'total_cost' ]; $v = bcsub( $v, $value, 2 ); $headers[ $cont_key ][ 'total_cost' ] = $v; // subtract deleted spots and value from campaign 'detail_*' totals $campaigns[0][ 'detail_spots' ] -= $spots; $v = $campaigns[0][ 'detail_cost' ]; $v = bcsub( $v, $value, 2 ); $campaigns[0][ 'detail_cost' ] = $v; // subtract deleted spots and value from campaign 'total_*' totals $campaigns[0][ 'total_spots' ] -= $spots; $v = $campaigns[0][ 'total_cost' ]; $v = bcsub( $v, $value, 2 ); $campaigns[0][ 'total_cost' ] = $v; // Now re-validate everything, and re-display this // specific contract. next_state( 'RE-VERIFY_CAMPAIGN' ); break; ///////////////////////////////// // // Delete a Network from a contract // ///////////////////////////////// case ($ps_state == 'DELETE_NETWORK'): next_state( 'BEGIN' ); $lineID = $_SESSION[ 'LineID' ]; // XML LineID number $network = NULL; foreach ($details[ $cont_key ] as $det) { if ($det[ 'LineID' ] === $lineID) { $network = $det[ 'Network' ]; //echo "<pre>"; var_dump( $det ); echo "</pre>"; break; } } next_state( 'RE-VERIFY_CAMPAIGN' ); if (is_null( $network)) { message_log_append( $msg_log, 'Invalid LineID: ' . $lineID . ' not found in contract key ' . $cont_key ); break; } // Deleting detail lines will change the header spot and value totals. // delete_detail_network is responsible for telling us how many spots // were deleted, and what their total value was. $spots = 0; $value = 0; $details[ $cont_key ] = delete_detail_network( $details[ $cont_key ], $network, $spots, $value ); // subtract deleted spots and value from header 'detail_*' totals $headers[ $cont_key ][ 'detail_spots' ] -= $spots; $v = $headers[ $cont_key ][ 'detail_cost' ]; $v = bcsub( $v, $value, 2 ); $headers[ $cont_key ][ 'detail_cost' ] = $v; // subtract deleted spots and value from header 'total_*' totals $headers[ $cont_key ][ 'total_spots' ] -= $spots; $v = $headers[ $cont_key ][ 'total_cost' ]; $v = bcsub( $v, $value, 2 ); $headers[ $cont_key ][ 'total_cost' ] = $v; // subtract deleted spots and value from campaign 'detail_*' totals $campaigns[0][ 'detail_spots' ] -= $spots; $v = $campaigns[0][ 'detail_cost' ]; $v = bcsub( $v, $value, 2 ); $campaigns[0][ 'detail_cost' ] = $v; // subtract deleted spots and value from campaign 'total_*' totals $campaigns[0][ 'total_spots' ] -= $spots; $v = $campaigns[0][ 'total_cost' ]; $v = bcsub( $v, $value, 2 ); $campaigns[0][ 'total_cost' ] = $v; message_log_append( $msg_log, 'Network ' . $network . ' deleted from contract ' . $cont_key ); // Now re-validate everything, and re-display this // specific contract. next_state( 'RE-VERIFY_CAMPAIGN' ); break; ///////////////////////////////// // // Delete an entire contract // ///////////////////////////////// case ($ps_state == 'DELETE_CONTRACT'): //message_log_append( $msg_log, 'You requested to delete contract ' . $cont_key ); // Unset the individual detail lines for this contract. $dkeys = array_keys( $details[ $cont_key ] ); foreach ($dkeys as $key) { unset( $details[ $cont_key ][ $key ] ); } // subtract contract spots and value from campaign 'detail_*' totals $spots = $headers[ $cont_key ][ 'detail_spots' ]; $value = $headers[ $cont_key ][ 'detail_cost' ]; $campaigns[0][ 'detail_spots' ] -= $spots; $v = $campaigns[0][ 'detail_cost' ]; $v = bcsub( $v, $value, 2 ); $campaigns[0][ 'detail_cost' ] = $v; // subtract contract spots and value from campaign 'total_*' totals $spots = $headers[ $cont_key ][ 'total_spots' ]; $value = $headers[ $cont_key ][ 'total_cost' ]; $campaigns[0][ 'total_spots' ] -= $spots; $v = $campaigns[0][ 'total_cost' ]; $v = bcsub( $v, $value, 2 ); $campaigns[0][ 'total_cost' ] = $v; // Set the contract header to show 0 spots, 0 value. $spots = 0; $value = 0; $headers[ $cont_key ][ 'detail_spots' ] = $spots; $headers[ $cont_key ][ 'detail_cost' ] = $value; $headers[ $cont_key ][ 'total_spots' ] = $spots; $headers[ $cont_key ][ 'total_cost' ] = $value; // Unset the 'versionN' fields of deleted contracts so that version // problems don't prevent the remaining contracts from being imported. $j = 0; $done = FALSE; while (!$done) { $fld = 'version' . (++$j); $done = !isset( $headers[ $cont_key ][ $fld ] ); unset( $headers[ $cont_key ][ $fld ] ); } // while // auto-advance to next contract $done = FALSE; $keys = array_keys( $headers ); $cont_key = next_cont_key( $cont_key, $keys ); // we might someday use a better state than BEGIN here. A NULL // return from next_cont_key would mean that no contracts remain. next_state( is_null( $cont_key ) ? 'BEGIN' : 'RE-VERIFY_CAMPAIGN' ); break; ///////////////////////////////// // // Dummy stub. // ///////////////////////////////// case ($ps_state == 'DEAD_END'): case ($ps_state == 'STOP'): echo $ps_state; next_state( 'BEGIN' ); $done = TRUE; break; ///////////////////////////////// // // Screen has error messages. // Force user to go back and retry. // ///////////////////////////////// case ($ps_state == 'TRY_AGAIN'): next_state( 'BEGIN' ); echo nav_buttons( NULL, FALSE ); // Cancel only $done = TRUE; break; ///////////////////////////////// // // State is unknown or invalid. // Go back to BEGIN state. // ///////////////////////////////// default: message_log_append( $msg_log, 'Invalid state label: ' . $ps_state, MSG_LOG_ERROR ); next_state( 'BEGIN' ); $done = TRUE; } // switch $ps_state = current_state(); // echo message_log_format( $msg_log ); echo message_log_table( $msg_log ); } while (!$done); $_SESSION[ 'campaigns' ] = $campaigns; $_SESSION[ 'headers' ] = $headers; $_SESSION[ 'details' ] = $details; $_SESSION[ 'cont_key' ] = $cont_key; } // process_state
function verify_all_contracts( &$campaign_array, &$header_array, &$detail_array ) // Examine the header and detail arrays and attempt to find // all possible flaws with the data. // Return TRUE if no flaws can be found, else FALSE. { GLOBAL $msg_log; //GLOBAL $DEBUG; // for starters, the two arrays must be indexed the same. // $header_array is an array of rows. $detail_array is an // $array of arrays. Each row in $detail_array is in fact // an array of rows, such that the rows in $detail_array[x] // correspond to the header row in $header_array[x]. $success = TRUE; //if ($DEBUG) { echo "<pre>VAC: detail_array:\n"; var_dump( $detail_array ); echo "</pre>\n"; die(); } // Before we do anything, the header array and detail array keys must match $header_keys = array_keys( $header_array ); $detail_keys = array_keys( $detail_array ); if ($header_keys != $detail_keys) { $success = FALSE; $msg = "Internal error: header and detail array indexes differ"; message_log_append( $msg_log, $msg, MSG_LOG_ERROR ); if ($DEBUG){ echo "<pre>VAC keys don't match: header_keys:\n"; var_dump( $header_keys ); echo "</pre>\n"; } if ($DEBUG){ echo "<pre>VAC: detail_keys:\n"; var_dump( $detail_keys ); echo "</pre>\n"; } } // if $done = (!$success); if (!$done) { //if ($DEBUG) //{ echo "<pre>VAC: header_keys: "; var_dump( $header_keys ); echo "</pre>\n"; } // message_log_reset( $msg_log ); foreach ($header_keys as $key) { $hdr = $header_array[ $key ]; $det = $detail_array[ $key ]; // The code below that thinks one header record can have multiple // site records is really cumbersome and confuses some assumptions // made elsewhere. // The header array could have multiple Site Records. // We'll store one Log for each Site Record, in an array // that is indexed to match the $hdr['Site Records'] array. $header_array[ $key ][ 'MSG_LOG' ] = array(); foreach ($hdr[ 'Site Records' ] as $site_record) { // kludge! $hdr[ 'SiteName' ] = $site_record[ 'SiteName' ]; if (verify_one_contract( $campaign_array[ 0 ], $hdr, $detail_array[ $key ] )) { ; } else { $success = FALSE; } // if $header_array[ $key ][ 'MSG_LOG' ][] = $hdr[ 'MSG_LOG' ]; // message_log_reset( $msg_log ); } // foreach site_record $header_array[ $key ][ 'detail_spots' ] = $hdr[ 'detail_spots' ]; $header_array[ $key ][ 'detail_cost' ] = $hdr[ 'detail_cost' ]; } // foreach header } // if return( $success ); } // verify_all_contracts