Example #1
0
     $response = json_decode($gen_report);
     if ($response) {
         echo "Downloading " . $date->Text . "...\n";
         $filename = str_replace('/', '-', $date->Text) . '.zip';
         $fp = fopen($filename, 'w');
         $ch = curl_init($response->d);
         curl_setopt($ch, CURLOPT_FILE, $fp);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
         curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
         curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
         $invoice_file = curl_exec($ch);
         curl_close($ch);
         fclose($fp);
         echo "Importing invoices for " . $date->Text . "\n";
         if (UIGLib::import($filename, $repeat) === true) {
             unlink($filename);
         } else {
             echo "ERROR: IMPORT FAILED!\n";
         }
     }
     // only download one day for now
     // remove when done testing
     //break;
     // politeness; pause between requests
     sleep(15);
 }
 /**
   Cleanup: delete cookie file
 */
 unlink($cookies);
Example #2
0
 public function run()
 {
     global $FANNIE_OP_DB, $FANNIE_PLUGIN_SETTINGS;
     $dbc = FannieDB::get($FANNIE_OP_DB);
     $UNFI_USERNAME = $FANNIE_PLUGIN_SETTINGS[$this->username_field];
     $UNFI_PASSWORD = $FANNIE_PLUGIN_SETTINGS[$this->password_field];
     $LOGIN_URL = 'https://customers.unfi.com/_login/LoginPage/Login.aspx';
     $IFRAME_DOMAIN = 'https://stsuser.unfi.com';
     $HOME_URL = 'https://customers.unfi.com/_trust/pages/home.aspx';
     $SESSION_URL = 'https://stsuser.unfi.com/default.aspx/GetSessionValue';
     $INVOICE_URL = 'https://customers.unfi.com/Pages/ReportDetail.aspx?ReportID=41&ReportName=Invoices%20Download';
     $REPORT_GEN_URL = 'https://customers.unfi.com/_layouts/15/UNFI.UPO.WP.DynamicReportParams/AjaxBridge.aspx/SaveReportParams';
     $cookies = tempnam(sys_get_temp_dir(), 'cj_');
     /**
       Step 1:
       Download the login page
     */
     $ch = curl_init($LOGIN_URL);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
     curl_setopt($ch, CURLOPT_AUTOREFERER, true);
     curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
     curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
     $login_page = curl_exec($ch);
     curl_close($ch);
     /**
       Get hidden fields from login page
     */
     $inputs_regex = '/<input .*?name="(.+?)" .*?value="(.*?)"/';
     preg_match_all($inputs_regex, $login_page, $matches);
     $login_post = '';
     for ($i = 0; $i < count($matches[1]); $i++) {
         $login_post .= $matches[1][$i] . '=' . urlencode($matches[2][$i]) . '&';
     }
     /**
       add username and password
     */
     $login_post .= 'userName='******'&Password='******'t set, you won't get a valid
       result.
     
       Posting the token to the home URL return an HTTP 403
       and a page saying you need to login first. This is not
       accurate. Subsequent requests will be logged in.
     */
     $iframe_regex = '/<iframe .*src="(.*?)"/';
     preg_match_all($iframe_regex, $body, $matches);
     foreach ($matches[1] as $url) {
         $full_url = $IFRAME_DOMAIN . '/' . $url;
         $ch = curl_init($full_url);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
         curl_setopt($ch, CURLOPT_AUTOREFERER, true);
         curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
         curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
         curl_setopt($ch, CURLOPT_HEADER, true);
         curl_setopt($ch, CURLOPT_REFERER, $referer);
         $iframe = curl_exec($ch);
         curl_close($ch);
         preg_match_all($inputs_regex, $iframe, $matches);
         $post_data = '';
         for ($i = 0; $i < count($matches[1]); $i++) {
             // complication; convert undo html encoding in the xml
             // e.g., &lt and then reencode for url
             // e.g., %3C
             $post_data .= $matches[1][$i] . '=' . urlencode(htmlspecialchars_decode($matches[2][$i]));
             if ($i < count($matches[1]) - 1) {
                 $post_data .= '&';
             }
         }
         $ch = curl_init($HOME_URL);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
         curl_setopt($ch, CURLOPT_AUTOREFERER, true);
         curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
         curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
         curl_setopt($ch, CURLOPT_HEADER, true);
         curl_setopt($ch, CURLOPT_POST, true);
         curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
         curl_setopt($ch, CURLOPT_REFERER, $full_url);
         $body = curl_exec($ch);
         $referer = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
         curl_close($ch);
     }
     /**
     Requesting session value isn't necessary
     Using a browser does this but I never get
     a valid result when using the script and it
     doesn't seem to matter.
     $ch = curl_init($SESSION_URL);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
     curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
     curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
     curl_setopt($ch, CURLOPT_HEADER, true);
     curl_setopt($ch, CURLOPT_POST, true);
     curl_setopt($ch, CURLOPT_POSTFIELDS, '');
     $session_page = curl_exec($ch);
     curl_close($ch);
     */
     /**
       Get invoice download page
     */
     $ch = curl_init($INVOICE_URL);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
     curl_setopt($ch, CURLOPT_HEADER, true);
     curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
     curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
     $invoice_page = curl_exec($ch);
     curl_close($ch);
     // not sure if this is actually needed
     // browser ends up with this cookie
     $fp = fopen($cookies, 'a');
     fwrite($fp, "customers.unfi.com\tFALSE\t/\tFALSE\t0]\tWSS_FullScreenMode\tfalse\n");
     fclose($fp);
     /**
       Extract available dates
       They're now embedded in javascript as JSON list
       of objects instead of being in a <select> field
     */
     $dates = array();
     $json_regex = '/dataSource: (\\[.*?\\])/';
     preg_match_all($json_regex, $invoice_page, $matches);
     foreach ($matches[1] as $match) {
         $data = json_decode($match);
         if (strtotime($data[0]->Text)) {
             $dates = $data;
             break;
         }
     }
     /**
       Extract inputs by id
       They contain some useful information for the
       actual downloads.
     */
     $id_regex = '/<input .*?id="(.+?)" .*?value="(.*?)"/';
     preg_match_all($id_regex, $invoice_page, $matches);
     $inputs = array();
     for ($i = 0; $i < count($matches[1]); $i++) {
         $inputs[$matches[1][$i]] = $matches[2][$i];
     }
     // I think only this one needs to be decoded
     if (isset($inputs['claims'])) {
         $inputs['claims'] = json_decode(htmlspecialchars_decode($inputs['claims']));
     }
     $check = $dbc->prepare('SELECT orderID FROM PurchaseOrder WHERE vendorID=? and userID=0
                         AND creationDate=? AND placedDate=?');
     $temp_dir = sys_get_temp_dir();
     foreach ($dates as $date) {
         $good_date = date('Y-m-d', strtotime($date->Text));
         $doCheck = $dbc->execute($check, array($this->vendor_id, $good_date, $good_date));
         $diff = time() - strtotime($date->Text);
         $repeat = false;
         if ($dbc->num_rows($doCheck) > 0 && $diff > 3 * 24 * 60 * 60) {
             continue;
         } else {
             if ($dbc->num_rows($doCheck) > 0) {
                 $repeat = true;
             }
         }
         /**
           POST a JSON value to request a particular report
           The response will be a simple JSON object containing
           the actual file URL.
           { "d" : "http://customer.unfi.com/path/to/file.zip" }
         */
         $cv = 'CustomerNumber->>' . $inputs['hdnCustomerNumber'];
         $cv .= '||InvoiceDate->>' . $date->Value;
         $cv .= '||SelectedChain->>' . $inputs['hdnCustomerNumber'];
         $cv .= '||Delimiter->>csv||Hyphen->>0';
         $cv .= '||ReportPath->>' . $inputs['hdnReportPath'];
         $json_request = array('ControlsAndValues' => $cv, 'ReportOptions' => 'zip', 'userID' => $inputs['claims']->UserId, 'reportID' => 41, 'customerNumber' => $inputs['hdnCustomerNumber'], 'emailAddress' => $inputs['claims']->EmailAddress, 'chainAccounts' => '', 'actionType' => 'Save');
         $ch = curl_init($REPORT_GEN_URL);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
         curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
         curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
         curl_setopt($ch, CURLOPT_REFERER, $INVOICE_URL);
         curl_setopt($ch, CURLOPT_POST, true);
         $json = json_encode($json_request);
         $json = str_replace("\\", '', $json);
         $json = str_replace('"reportID":41', '"reportID":"41"', $json);
         curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
         // authorization is definitely needed; the rest may
         // or may not be. Debugging took awhile
         curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json; charset=utf-8", 'Authorization: ' . $inputs['hfTokValidator'], 'X-Requested-With: XMLHttpRequest', 'Accept: application/json, text/javascript, */*; q=0.01', 'Accept-Language: en-US,en;q=0.5', 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:28.0) Gecko/20100101 Firefox/28.0', 'Pragma: no-cache', 'Cache-Control: no-cache'));
         $gen_report = curl_exec($ch);
         curl_close($ch);
         $response = json_decode($gen_report);
         if ($response) {
             $filename = $temp_dir . '/' . str_replace('/', '-', $date->Text) . '.zip';
             $fp = fopen($filename, 'w');
             $ch = curl_init($response->d);
             curl_setopt($ch, CURLOPT_FILE, $fp);
             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
             curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
             curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
             curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
             $invoice_file = curl_exec($ch);
             curl_close($ch);
             fclose($fp);
             $this->cronMsg("Importing invoices for " . $date->Text, FannieLogger::INFO);
             if (UIGLib::import($filename, $this->vendor_id, $repeat) === true) {
                 unlink($filename);
             } else {
                 $this->cronMsg("ERROR: IMPORT FAILED!", FannieLogger::ERROR);
             }
             // only download one day for now
             // remove when done testing
             //break;
         }
         // politeness; pause between requests
         sleep(15);
     }
     /**
       Cleanup: delete cookie file
     */
     unlink($cookies);
 }