Reputation: 343
We are using Woocommerce for our ecom website and in order to automatically generate government-approved invoices for customers we use a certified online invoicing software.
I am making an API request to this invoicing software in order to retrieve the generated invoice document from their database, this is the code:
// On Order complete > Get document ID from order > access Moloni invoicing API > get document link GETPDFLINK > Sanitize the string and get Hash > generate the final document link > access it and download the PDF
function download_moloni_document_id( $order_id, $order ) {
// Retreive from the Database table moloni_api the access token from column main_token
global $wpdb;
$table_name = "db_invoicing_api";
$retrieve_data = $wpdb->get_results( "SELECT * FROM $table_name WHERE id = 1" );
foreach ($retrieve_data as $retrieved_data) {
$maintoken = $retrieved_data->main_token;
}
// Get document ID from the order
$documentid = get_post_meta($order->id, '_moloni_sent', true);
// Connect to moloni API and getpdflink
$url = "https://api.moloni.pt/v1/documents/getPDFLink/?access_token=$maintoken";
$postData = array(
'company_id' => '12345',
'document_id' => $documentid );
$arguments = array(
'method' => 'POST',
'headers' => array(
'Content-type: application/x-www-form-urlencoded'
),
'body' => $postData,
);
$response = wp_remote_post( $url, $arguments );
if ( is_wp_error( $response ) ) {
$error_message = $response->get_error_message();
return "Something went wrong: $error_message";
} else {
echo '<pre>';
var_dump( wp_remote_retrieve_body( $response ) );
echo '</pre>';
// jsondecode the string received by the API to remove backslashes, get and parse the URL and extract the HASH key
$response2 = wp_remote_retrieve_body($response);
parse_str(parse_url(json_decode($response2, true)['url'], PHP_URL_QUERY), $result);
$hash = $result['h'];
// Assemble the Invoice HTML download URL with the Hash and document ID
$fileUrlpdf = "https://www.moloni.pt/downloads/index.php?action=getDownload&h=$hash&d=$documentid&e=$loginmail&i=1&t=n";
$pdforderid = $order->id;
// Save the file with document id name to server location
$saveTopdf = "ftp://myserver/INVOICES/evo-$pdforderid.PDF";
file_put_contents(
$saveTopdf,
file_get_contents($fileUrlpdf)
);
} }
add_action( 'woocommerce_order_status_completed', 'download_moloni_document_id', 20, 2 );
In the end you can see I use
file_put_contents(
$saveTopdf,
file_get_contents($fileUrlpdf) );
in order to visit the link, retrieve the PDF and download it. This works well then the link is generated successfully and sends to a direct download of the invoice PDF The problem I have is is, sometimes there is an issue and the invoice PDF is not generated, this makes it so that the final link $fileUrlpdf does not lead to a download but instead to a web page with an error message saying something like "No Documents Found" which leads this code to download a PDF of dozens of pages containing the source code/HTML of that page. This is a problem because the PDFs (invoices) are later automatically printed by our system, so we sometimes end up with hundreds of pages of HTML code instead of the invoices.
I have tried to solve this in the following way through conditions:
to check if the download/PDF file exists
if (file_exists($fileUrlpdf)) {
file_put_contents(
$saveTopdf,
file_get_contents($fileUrlpdf)); }
one that would check the $response array for the error message and not proceed (because
$invalid = 'No Documents Found'; if (strpos($response, $valid) !== false) {echo 'No Documents found'; else { *download the PDF* } }
I have also considered the possibility of
Bear with me as you can see my experience with PHP is limited so I would like to ask, what would be the best practice here? What approach would you suggest?
Thank you very much in advance for the attention and advice.
Upvotes: 0
Views: 113
Reputation: 148
Either look at using the API to fetch the invoice/document and handle errors that way moloni.pt/dev
Or you could look at checking the Content-Type of the response headers as shown below
$fileUrlpdf = "https://www.moloni.pt/downloads/index.php?action=getDownload&h=$hash&d=$documentid&e=$loginmail&i=1&t=n";
$fileHeaders = get_headers($fileUrlpdf, true)
if($fileHeaders['Content-Type'] === 'application/pdf') {
// PDF response
}
Upvotes: 1