'division', 'Consignee' => 'consignee', 'Called In' => 'date_called_in', 'Dispatch #' => 'dispatch_number', 'Shipper' => 'shipper', 'Ready' => 'date_ready', 'Address 1' => 'address_1', 'Address 2' => 'address_2', 'City' => 'city', 'ST' => 'state', 'Zip' => 'zip', 'Phone' => 'phone', 'Ready Time' => 'time_ready', 'Close Time' => 'time_close', 'Pickup Time' => 'time_pickup', 'Depart Time' => 'time_depart', 'BOL Delivered' => 'bol_delivered', 'Dispatch Refere' => 'dispatch_reference', 'Ctns' => 'ctns', 'Weight' => 'weight', 'Cube' => 'cube' ); $fields_by_col = array(); $path = '../data'; //scan respective directories for new files $companies = getCompanyDirectories(); for($c = 0; $c < count($companies); $c++) { $company = $companies[$c]; $id_company = $company['id_company']; $name = $company['name']; $ftp_directory = $company['ftp_directory']; $ftp_full_path = "$path/$ftp_directory"; echo "scanning #$id_company $name\t$ftp_full_path:\t"; //check if the directory exists if(!file_exists($ftp_full_path) || !is_dir($ftp_full_path)) { echo "directory not found\n"; continue; } //find all spreadsheets $files = glob("$ftp_full_path/*.xls"); echo 'found ' . count($files) . ' excel spreadsheet(s)' . PHP_EOL; //go through each one foreach($files as $full_path) { processFile($full_path, $id_company); echo PHP_EOL; } } function processFile($full_path, $id_company) { global $dbh; if(!file_exists($full_path)) { echo "file doesn't exist" . PHP_EOL; return false; } $dir = dirname($full_path); $filename = basename($full_path); $file_size = filesize($full_path); $file_hash = md5_file($full_path); //first try to find if the file exists $stmt_file = $dbh->prepare( "SELECT id_file FROM file WHERE filename = :filename AND md5_hash = :file_hash AND size = :file_size"); $params = array( ':filename' => $filename, ':file_hash' => $file_hash, ':file_size' => $file_size ); $stmt_file->execute($params); $rows = $stmt_file->fetchAll(PDO::FETCH_ASSOC); //figure out if we are reprocessing if(count($rows)) { $id_file = $rows[0]['id_file']; echo "re-processing file #$id_file" . PHP_EOL; } else { //report file processed $stmt_file = $dbh->prepare("INSERT INTO file (id_company, dir, filename, md5_hash, size) VALUES (:id_company, :dir, :filename, :file_hash, :file_size)"); $params = array( ':id_company' => $id_company, ':dir' => dirname($full_path), ':filename' => basename($filename), ':file_size' => $file_size, ':file_hash' => $file_hash ); if(!$stmt_file->execute($params)) { echo "PDO::errorInfo():" . PHP_EOL; print_r($dbh->errorInfo()); return false; } $id_file = $dbh->lastInsertId(); echo "processing new file #$id_file" . PHP_EOL; } //insert row $stmt_row = $dbh->prepare("INSERT INTO file_row ( id_file, row_number, division, consignee, date_called_in, dispatch_number, shipper, date_ready, address_1, address_2, city, state, zip, phone, time_ready, time_close, time_pickup, time_depart, bol_delivered, dispatch_reference, ctns, weight, cube ) VALUES ( :id_file, :row_number, :division, :consignee, STR_TO_DATE(:date_called_in, '%m/%d/%Y'), :dispatch_number, :shipper, STR_TO_DATE(:date_ready, '%m/%d/%Y'), :address_1, :address_2, :city, :state, :zip, :phone, :time_ready, :time_close, :time_pickup, :time_depart, :bol_delivered, :dispatch_reference, :ctns, :weight, :cube ) ON DUPLICATE KEY UPDATE division = :division, consignee = :consignee, date_called_in = STR_TO_DATE(:date_called_in, '%m/%d/%Y'), dispatch_number = :dispatch_number, shipper = :shipper, date_ready = STR_TO_DATE(:date_ready, '%m/%d/%Y'), address_1 = :address_1, address_2 = :address_2, city = :city, state = :state, zip = :zip, phone = :phone, time_ready = :time_ready, time_close = :time_close, time_pickup = :time_pickup, time_depart = :time_depart, bol_delivered = :bol_delivered, dispatch_reference = :dispatch_reference, ctns = :ctns, weight = :weight, cube = :cube"); if(!$stmt_row) { echo "PDO::errorInfo():" . PHP_EOL; print_r($dbh->errorInfo()); return false; } $num_rows = 0; try { //this is necessary to dramatically reduce the memory footprint $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp; $cacheSettings = array( ' memoryCacheSize ' => '8MB'); PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); // figure out which type it is $type = PHPExcel_IOFactory::identify($full_path); // create an excel reader object $reader = PHPExcel_IOFactory::createReader($type); $reader->setReadDataOnly(false); echo "xls detected as: $type" . PHP_EOL; // load the file $excel = $reader->load($full_path); // pull the 'call details' worksheet, which should be the only one $sheet = $excel->getSheet(0); // count the number of rows and columns $num_rows = $sheet->getHighestRow(); $last_column = $sheet->getHighestColumn(); // let's keep track of how many succeeded and failed $num_ok = 0; $num_fail = 0; $num_skip = 0; // pull column names $column_names = $sheet->rangeToArray('A1:' . $last_column . '1', NULL, TRUE, FALSE); $columns_by_names = array(); //flip the column names to reflect the indexes foreach($column_names[0] as $index => $name) if($name && strlen(trim($name))) $columns_by_names[$name] = $index; // go through and read each row for($r = 2; $r <= $num_rows; $r++) { $range = 'A' . $r . ':' . $last_column . $r; echo "processing row #$r..."; // read row of data into array $row_array = $sheet->rangeToArray($range, NULL, TRUE, TRUE); if(!count($row_array)) { echo "no data\n"; continue; } //pull the row out and format the nulls as needed $row = $row_array[0]; for($c = 0; $c < count($row); $c++) $row[$c] = $row[$c] && strlen(trim($row[$c])) ? trim($row[$c]) : null; //skip if no data for first three columns if(!$row[0] && !$row[1] && !$row[2]) { echo "SKIP\n"; $num_skip++; continue; } //bind appropriate values $params = array(); $params[':id_file'] = $id_file; $params[':row_number'] = $r; $params[':division'] = $row[0]; $params[':consignee'] = $row[1]; $params[':date_called_in'] = $row[2]; $params[':dispatch_number'] = $row[3]; $params[':shipper'] = $row[4]; $params[':date_ready'] = $row[5]; $params[':address_1'] = $row[6]; $params[':address_2'] = $row[7]; $params[':city'] = $row[8]; $params[':state'] = $row[9]; $params[':zip'] = $row[10]; $params[':phone'] = $row[11]; $params[':time_ready'] = $row[14] ? DateTime::createFromFormat('H:i A', $row[14])->format('H:i:s') : null; $params[':time_close'] = $row[15] ? DateTime::createFromFormat('H:i A', $row[15])->format('H:i:s') : null; $params[':time_pickup'] = $row[16] ? DateTime::createFromFormat('H:i A', $row[16])->format('H:i:s') : null; $params[':time_depart'] = $row[17] ? DateTime::createFromFormat('H:i A', $row[17])->format('H:i:s') : null; $params[':bol_delivered'] = $row[18]; $params[':dispatch_reference'] = $row[35]; $params[':ctns'] = $row[44]; $params[':weight'] = $row[45]; $params[':cube'] = $row[46]; try { $stmt_row->execute($params); echo "OK\n"; $num_ok++; } catch(Exception $e) { echo 'FAIL: ' . $e->getMessage() . "\n"; $num_fail++; } } } catch(Exception $e) { echo "Uncaught fatal error while attempting to process the downloaded report: " . $e->getMessage() . "\n"; } //update the final status $stmt_file_status = $dbh->prepare("UPDATE file SET num_rows = :num_rows, num_ok = :num_ok, num_fail = :num_fail, num_skip = :num_skip WHERE id_file = :id_file"); $params = array( ':id_file' => $id_file, ':num_rows' => $num_rows-1, //subtract one because of the column header ':num_ok' => $num_ok, ':num_fail' => $num_fail, ':num_skip' => $num_skip ); $stmt_file_status->execute($params); return true; } ?>