Headline
CVE-2023-4161: woocommerce-pdf-invoice-ajax.php in woo-pdf-invoice-builder/trunk – WordPress Plugin Repository
The WooCommerce PDF Invoice Builder for WordPress is vulnerable to Cross-Site Request Forgery due to a missing nonce check on the SaveCustomField function in versions up to, and including, 1.2.90. This makes it possible for unauthenticated attackers to create invoice fields provided they can trick an admin into performing an action such as clicking on a link.
1<?php2/**3 * Created by PhpStorm.4 * User: Edgar5 * Date: 10/10/20176 * Time: 7:50 AM7 */8910use rnwcinv\compatibility\DocumentOptionsCompatibility;11use rnwcinv\htmlgenerator\FieldDTO;12use rnwcinv\htmlgenerator\fields\FieldFactory;13use rnwcinv\htmlgenerator\OrderValueRetriever;14use rnwcinv\pr\CustomField\CustomFieldBase;15use rnwcinv\pr\CustomField\CustomFieldFactory;16use rnwcinv\pr\CustomField\SimpleCustomField;17use rnwcinv\pr\CustomField\utilities\CustomFieldValueRetriever;18use rnwcinv\pr\CustomFieldV2\BasicFields\CArrayField;19use rnwcinv\pr\CustomFieldV2\BasicFields\CImageField;20use rnwcinv\pr\CustomFieldV2\BasicFields\CSimpleField;21use rnwcinv\pr\utilities\FontManager;22use rnwcinv\utilities\InvoiceInitialDataGenerator;2324require_once RednaoWooCommercePDFInvoice::$DIR.’utilities/HttpPostProcessor.php’;25final class RednaoWooCommercePDFInvoiceAjax{26 public $data=null;27 public $detailCatched=false;28 public function __construct()29 {30 add_action(‘wp_ajax_rednao_wcpdfinv_get_field_preview’,array($this,’GetFieldPreview’));31 add_action(‘wp_ajax_rednao_wcpdfinv_get_qr_preview’,array($this,’GetQrPreview’));32 add_action(‘wp_ajax_rednao_wcpdfinv_save_custom_field’,array($this,’SaveCustomField’));33 add_action(‘wp_ajax_rednao_wcpdfinv_get_designer_preview’,array($this,’GetDesignerPreview’));34 add_action(‘wp_ajax_rednao_wcpdfinv_save’,array($this,’Save’));35 add_action(‘wp_ajax_rednao_search_invoice’,array($this,’SearchInvoice’));36 add_action(‘wp_ajax_rednao_check_if_order_is_valid’,array($this,’CheckIfOrderIsValid’));37 add_action(‘wp_ajax_rednao_wcpdfinv_generate_pdf’,array($this,’CreatePDF’));38 add_action(‘wp_ajax_rednao_update_template’,array($this,’UpdateTemplate’));39 add_action(‘wp_ajax_rednao_wcpdfinv_get_designer_export’,array($this,’Export’));40 add_action(‘wp_ajax_rednao_wcpdfinv_remind_me’,array($this,’RemindMeLater’));41 add_action(‘wp_ajax_rednao_wcpdfinv_dont_show_again’,array($this,’DontShowAgain’));42 add_action(‘wp_ajax_rednao_wcpdfinv_diagnose_error’,array($this,’DiagnoseError’));43 add_action(‘wp_ajax_rednao_wcpdfinv_get_latest_error’,array($this,’GetLatestError’));44 add_action(‘wp_ajax_rednao_wcpdfinv_dont_show_again_nl’,array($this,’DontShowNewsletter’));45 add_action(‘wp_ajax_rednao_wcpdfinv_inspect_order’,array($this,’InspectOrder’));46 add_action(‘wp_ajax_rednao_wcpdfinv_preview_custom_field’,array($this,’PreviewCustomField’));47 add_action(‘wp_ajax_rednao_wcpdfinv_get_invoice_details’,array($this,’GetInvoiceDetail’));48 add_action(‘wp_ajax_rednao_wcpdfinv_load_template’,array($this,’LoadTemplate’));49 add_action(‘wp_ajax_rednao_wcpdfinv_email_pdf’,array($this,’EmailPDF’));50 add_action(‘wp_ajax_rednao_wcpdfinv_delete_pdf’,array($this,’DeletePDF’));51 add_action(‘wp_ajax_rednao_wcpdfinv_manage_delete’,array($this,’ManageDelete’));52 add_action(‘wp_ajax_rednao_wcpdfinv_search’,array($this,’Search’));53 add_action(‘wp_ajax_rednao_wcpdfinv_manage_view’,array($this,’ManageView’));54 add_action(‘wp_ajax_rednao_wcpdfinv_download’,array($this,’Download’));55 add_action(‘wp_ajax_rednao_wcpdfinv_save_next_number’,array($this,’SaveNextNumber’));565758 }59606162 public function SaveNextNumber(){63 RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();64 $processor=new HttpPostProcessor();6566 $invoiceId=$processor->GetRequired(‘invoiceid’);67 $nextNumber=$processor->GetRequired(‘number’);6869 update_option($invoiceId. ‘_rednao_pdf_invoice_number’,apply_filters(‘wcpdfi_update_latest_invoice_number’,$nextNumber,$invoiceId));7071 $processor->SendSuccessMessage();72 }7374 public function ManageDelete(){75 RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();76 $processor=new HttpPostProcessor();77 $nonce=$processor->GetRequired(‘Nonce’);78 if(!wp_verify_nonce($nonce,’pdfi_manage_nonce’))79 die(‘Forbidden’);8081 $invoiceList=$processor->GetRequired(‘Invoices’);82 global $wpdb;83 $ids=’’;84 $allDeleted=true;85 foreach($invoiceList as $invoice)86 {87 $result=$wpdb->query($wpdb->prepare(‘delete from ‘.RednaoWooCommercePDFInvoice::$INVOICES_CREATED_TABLE. ' where invoice_id =%s and order_id=%s’,$invoice->InvoiceId,$invoice->OrderId));88 if($result==false)89 {90 $allDeleted=true;91 }92939495 }9697 if(!$allDeleted)98 {99 $this->SendErrorMessage(‘Some items could not be deleted, please try again’);100 }101102 $this->SendSuccessMessage(‘Items deleted successfully’);103 }104105 public function Download(){106 RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();107 $processor=new HttpPostProcessor();108 $nonce=$processor->GetRequired(‘Nonce’);109 if(!wp_verify_nonce($nonce,’pdfi_manage_nonce’))110 die(‘Forbidden’);111112 $invoiceList=$processor->GetRequired(‘Invoices’);113114 if(count($invoiceList)==1)115 {116 $orderId=$invoiceList[0]->OrderId;117 $invoiceId=$invoiceList[0]->InvoiceId;118 $order=wc_get_order($orderId);119 if($order==false)120 {121 echo "Invalid Order Number";122 die();123 }124125 require_once ‘PDFGenerator.php’;126127 $generator=\rnwcinv\GeneratorFactory::GetGenerator(RednaoPDFGenerator::GetPageOptionsById($invoiceId),$order);128 $generator->Generate(true,true);129130 header(“Content-type: application/pdf”);131 header("Content-disposition: attachment; filename=".basename($generator->GetFileName()).’.pdf’);132 header(‘Expires: 0’);133 header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);134 echo $generator->GetOutput();135136 die();137 }else{138139 $uploadDir=wp_upload_dir();140 $path= $uploadDir[‘basedir’].’/sf_pdfs_bulk’;141142 if(!is_dir($path))143 RednaoWooCommercePDFInvoice::CreateFolder($path);144145146 $zip=new \ZipArchive();147 $usedNames=[];148 $zip->open( $path.’documents.zip’,\ZipArchive::CREATE|\ZipArchive::OVERWRITE);149 foreach($invoiceList as $invoice)150 {151 $order=wc_get_order($invoice->OrderId);152 if($order==false)153 {154 echo "Invalid Order Number";155 die();156 }157158 require_once ‘PDFGenerator.php’;159160 $generator=\rnwcinv\GeneratorFactory::GetGenerator(RednaoPDFGenerator::GetPageOptionsById($invoice->InvoiceId),$order);161 $generator->Generate(true,true);162163164 $name=$generator->GetFileName();165 $nameToCheck=strtolower($name);166 $index=1;167 while(array_search($nameToCheck,$usedNames)!==false)168 {169 $nameToCheck=strtolower($name).’(‘.$index.’)‘;170 $index++;171 }172 $usedNames[]=$nameToCheck;173174175 $zip->addFromString($nameToCheck.’.pdf’,$generator->GetOutput());176 }177178179 header(“Content-Type: application/zip”);180 header(“Content-Disposition: attachment; filename=documents.zip”);181 header("Content-Length: " . filesize($path.’documents.zip’));182 readfile($path.’documents.zip’);183184185 $files = glob($path.’*’); // get all file names186 foreach($files as $file){ // iterate files187 if(is_file($file))188 unlink($file); // delete file189 }190191 die();192 }193 }194195 public function ManageView(){196 $orderId=$_GET[‘orderid’];197 $invoiceId=$_GET[‘invoiceid’];198 $nonce=$_GET[‘nonce’];199200 if(!wp_verify_nonce($nonce,’pdfi_manage_nonce’))201 die(‘Forbidden’);202203 $orderId=$_GET[‘orderid’];204 $order=wc_get_order($orderId);205 if($order==false)206 {207 echo “Invalid Order Number";208 die();209 }else{210 $invoiceId=-1;211 if(isset($_GET[‘invoiceid’]))212 $invoiceId=$_GET[‘invoiceid’];213 require_once ‘PDFGenerator.php’;214215 $generator=\rnwcinv\GeneratorFactory::GetGenerator(RednaoPDFGenerator::GetPageOptionsById($invoiceId),$order);216 $generator->GeneratePreview(true);217 die();218 }219 }220221 public function Search(){222 RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();223 $processor=new HttpPostProcessor();224 $startDate=$processor->GetRequired(‘StartDate’);225 $endDate=$processor->GetRequired(‘EndDate’);226 $customerName=$processor->GetRequired(‘CustomerName’);227 $invoiceNumber=$processor->GetRequired(‘InvoiceNumber’);228 $invoiceId=$processor->GetRequired(‘InvoiceId’);229230 RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();231232 global $wpdb;233 $where=$wpdb->prepare(‘invoice_id=%s’,$invoiceId);234235 if($startDate>0)236 {237 $where.=$wpdb->prepare(' and date>=FROM_UNIXTIME(%d)‘,$startDate);238 }239240 if($endDate>0)241 {242 $where.=$wpdb->prepare(' and date<=FROM_UNIXTIME(%d)‘,$endDate);243 }244245 if($customerName!=’’)246 {247 $where.=’ and user.display_name like \’%’.esc_sql($wpdb->esc_like($customerName)).’%\’’;248 }249250 if($invoiceNumber!=’’)251 {252 $where.=’ and formatted_invoice_number like \’%’.esc_sql($wpdb->esc_like($invoiceNumber)).’%\’’;253 }254255256 $results=$wpdb->get_results(“257 select invoice_id InvoiceId,order_id OrderId,UNIX_TIMESTAMP(date) Date,formatted_invoice_number FormattedInvoiceNumber,post.post_status Status,meta_total.meta_value Total,258 concat(coalesce(meta_firstname.meta_value,’’),\” \", coalesce(meta_lastname.meta_value,’’),\” (\",user.display_name,\")\") CustomerName259 from “.RednaoWooCommercePDFInvoice::$INVOICES_CREATED_TABLE.” created260 join “.$wpdb->posts.” post261 on created.order_id=post.ID262 left join “.$wpdb->postmeta.” meta_total263 on meta_total.post_id=post.ID and meta_total.meta_key=’_order_total’264 left join “.$wpdb->postmeta.” meta_user265 on post.ID=meta_user.post_id and meta_user.meta_key=’_customer_user’266 left join “.$wpdb->users.” user267 on user.ID=meta_user.meta_value 268 left join “.$wpdb->usermeta.” meta_firstname269 on user.ID=meta_firstname.user_id and meta_firstname.meta_key=’billing_first_name’270 left join “.$wpdb->usermeta.” meta_lastname271 on user.ID=meta_lastname.user_id and meta_lastname.meta_key=’billing_last_name’272 where 273 “.$where);274275 $processor->SendSuccessMessage($results);276277278279 }280281 public function DeletePDF(){282 $processor=new HttpPostProcessor();283 $OrderId=$processor->GetRequired(‘OrderId’);284 $InvoiceId=$processor->GetRequired(‘InvoiceId’);285 $nonce=$processor->GetRequired(‘Nonce’);286287 if(!wp_verify_nonce($nonce,’delete_’.$OrderId))288 {289 $processor->SendErrorMessage(‘Invalid request, please refresh and try again’);290 }291292 global $wpdb;293 $wpdb->delete(RednaoWooCommercePDFInvoice::$INVOICES_CREATED_TABLE,294 array(295 ‘invoice_id’=>$InvoiceId,296 ‘order_id’=>$OrderId297 ));298299 $this->SendSuccessMessage(‘’);300301 }302303 public function LoadTemplate()304 {305 RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();306307 $processor=new HttpPostProcessor();308 $source=$processor->GetRequired(‘source’);309 $fileName=preg_replace("/[^a-z0-9.]+/i", "",$processor->GetRequired(‘fileName’));310311 $path=RednaoWooCommercePDFInvoice::$DIR;312 if($source==’pr’)313 $path.=’pr/’;314 else315 $path.=’js/’;316 $path.=’templates/’.$fileName.’.json’;317318 if(!file_exists($path))319 $processor->SendErrorMessage(‘Template does not exists!’);320 $content=file_get_contents($path);321 $content=json_decode($content);322323 $content->containerOptions=json_decode($content->containerOptions);324 $content->pages=json_decode($content->pages);325 if($content->pages==false)326 $content->pages=[];327328 $content=DocumentOptionsCompatibility::execute($content);329 $processor->SendSuccessMessage($content);330 }331332 public function EmailPDF(){333 $processor=new HttpPostProcessor();334 $To=$processor->GetRequired(‘To’);335 $Subject=$processor->GetRequired(‘Subject’);336 $Body=$processor->GetRequired(‘Body’);337 $OrderId=$processor->GetRequired(‘OrderId’);338 $InvoiceId=$processor->GetRequired(‘InvoiceId’);339 $nonce=$processor->GetRequired(‘Nonce’);340 $saveTemplate=$processor->GetRequired(‘SaveTemplate’);341 // RednaoWooCommercePDFInvoice::CheckIfPDFAdmin();342 if(!wp_verify_nonce($nonce,’pdfi_manage_nonce’))343 {344 $processor->SendErrorMessage(‘Invalid request, please refresh and try again’);345 }346347 global $wpdb;348 if($saveTemplate&&RednaoWooCommercePDFInvoice::IsPR())349 {350 $wpdb->update(RednaoWooCommercePDFInvoice::$INVOICE_TABLE,array(351 'email_config’=>json_encode(array(352 'Subject’=>$Subject,353 'Body’=>$Body354 ))355 ),array(‘invoice_id’=>$InvoiceId));356357 }358359360361 $order=wc_get_order($OrderId);362 if($order==false)363 {364 $processor->SendSuccessMessage(‘Invalid order number’);365 die();366 }else{367 require_once RednaoWooCommercePDFInvoice::$DIR. ‘PDFGenerator.php’;368 $options=RednaoPDFGenerator::GetPageOptionsById($InvoiceId);369 //remove printer so it is not printed automatically370 for($i=0;$i<count($options->extensions);$i++)371 {372 if($options->extensions[$i]->extensionId==’printer’)373 {374 array_splice($options->extensions,$i,1);375 }376 }377 $generator=\rnwcinv\GeneratorFactory::GetGenerator($options,$order);378 $tmp_path = RednaoWooCommercePDFInvoice::GetSubFolderPath(‘attachments’);379 $tempFolderToReturn=’’;380 while(is_dir($tempFolderToReturn=$tmp_path.’temp’.$i.’/’))381 {382 $i++;383 }384385 if(!\mkdir($tempFolderToReturn))386 throw new Exception('Could not create folder '.$tempFolderToReturn);387388 $tmp_path=$tempFolderToReturn;389390391392 $attachments=array();393 $generator->GenerateAttachment($tmp_path,$attachments,0);394 if(RednaoWooCommercePDFInvoice::IsPR())395 {396 ini_set('display_errors’, 0);397 $tagManager=new \rnwcinv\pr\Manager\TagManager($generator->orderValueRetriever);398 $Subject=$tagManager->Process($Subject);399 }400401 $headers = array(‘Content-Type: text/html; charset=UTF-8’);402 do_action('rnwcinv_send_pdf_email’,$order->get_id(),$InvoiceId);403404 $emailData=(Object)[405 'Order’=>$order,406 'InvoiceId’=>$InvoiceId,407 'To’=>$To,408 'Subject’=>$Subject,409 ‘Body’=>$Body,410 ‘Attachments’=>$attachments,411 ‘Headers’=>$headers412 ];413414 $emailData=apply_filters(‘rnwcinv_before_sending_email’,$emailData);415416 $result=wp_mail($emailData->To,$emailData->Subject,$emailData->Body,$emailData->Headers,$emailData->Attachments);417 if($result==false)418 $this->SendErrorMessage(‘The email could not be send, please try again’);419 else420 $processor->SendSuccessMessage(‘’);421 die();422 }423 }424425 public function GetInvoiceDetail(){426 $processor=new HttpPostProcessor();427 $orderNumber=$processor->GetRequired(‘OrderNumber’);428 $invoiceId=$processor->GetRequired(‘InvoiceId’);;429430 global $wpdb;431 $row=$wpdb->get_row($wpdb->prepare(‘select invoice_number InvoiceNumber,formatted_invoice_number FormattedInvoiceNumber,unix_timestamp(date) Date from ‘.RednaoWooCommercePDFInvoice::$INVOICES_CREATED_TABLE.432 ' where order_id=%s and invoice_id=%s’,$orderNumber,$invoiceId));433434435 $this->SendSuccessMessage($row);436 }437438 public function PreviewCustomField(){439 error_reporting(E_ERROR);440 $processor=new HttpPostProcessor();441 $options=$processor->GetRequired(‘Options’);442 CustomFieldValueRetriever::$order=new WC_Order($options->OrderNumber);443444 if($options->FieldType==’table’)445 {446 $lineItems=CustomFieldValueRetriever::$order->get_items();447 if(count($lineItems)>0)448 {449 $value=reset($lineItems);450 CustomFieldValueRetriever::$lineItem = $value;451 }452453 }454455 if(isset($options->OrderFields)&&count($options->OrderFields)>0&&$options->OrderFields[0]->dataType==’array’)456 {457 $orderField=$options->OrderFields[0];458459 $this->SendSuccessMessage(array(‘html’=>(new CArrayField($orderField->fieldType,$orderField->source,$orderField->key))->GetHTML()));460 }461462 $preview=’’;463 foreach($options->OrderFields as $field)464 {465 $subTypeData=null;466 if(isset($field->subTypeData))467 $subTypeData=$field->subTypeData;468 $integration=null;469 if(isset($field->integration))470 $integration=$field->integration;471 $preview=’’;472 if($field->fieldType==’rnepo’)473 {474 $preview.=$field->html;475 }476477478 if($options->FormattingOptions->Type==’image’)479 {480 $preview.=(new CImageField($field->fieldType,$field->source,$field->path,$integration,$subTypeData,$options->FormattingOptions->Width,$options->FormattingOptions->Height))->GetHTML().’ ‘;481 }else if($options->FormattingOptions->Type==’qrcode’)482 {483 $preview.=(new CSimpleField($field->fieldType,$field->source,$field->path,$integration,$subTypeData))->GetStringValue().’ ‘;484485 require_once RednaoWooCommercePDFInvoice::$DIR.’vendor/phpqrcode/qrlib.php’;486 $svgCode = \QRcode::svg($preview,false,QR_ECLEVEL_L,3,0);487 $preview= ‘<img src="data:image/svg+xml;base64,’ . base64_encode($svgCode).’"></img>’;488489490 } else491 $preview.=(new CSimpleField($field->fieldType,$field->source,$field->path,$integration,$subTypeData))->GetHTML().’ ‘;492 }493 $this->SendSuccessMessage(array(‘html’=>$preview));494495496 }497498 public function GetQrPreview(){499 $options=(object)$this->GetArrayValue(‘options’);500 $field=FieldFactory::GetField($options,new OrderValueRetriever(null,null,true,null,null));501 $this->SendSuccessMessage(array(‘image’=>$field->GetImage()));502 }503504 public function InspectOrder(){505 $processor=new HttpPostProcessor();506507 $orderNumber=$processor->GetRequired(‘OrderNumber’);508 $type=$processor->GetRequired(‘Type’);509510 require_once RednaoWooCommercePDFInvoice::$DIR.’utilities/WCInspector.php’;511 $inspector=new WCInspector($orderNumber);512513 if($type==’normal’)514 $processor->SendSuccessMessage($inspector->InspectOrder());515 else516 if($type==’row’)517 $processor->SendSuccessMessage($inspector->InspectPossibleRows());518 else519 $processor->SendSuccessMessage($inspector->InspectOrderDetails());520 die();521522 }523524 public function SearchInvoice(){525 $processor=new HttpPostProcessor();526527 $criteria=$processor->GetRequired(‘SearchCriteria’);528529 global $wpdb;530531532533 $query = “534 select wp_posts.ID OrderNumber,invoice_date_meta.meta_value Date, invoice_number_meta.meta_value InvoiceNumber535 from “.$wpdb->posts.” 536 join “.$wpdb->postmeta.” invoice_date_meta537 on invoice_date_meta.post_id=wp_posts.ID and invoice_date_meta.meta_key=’REDNAO_WCPDFI_INVOICE_DATE’538 join “.$wpdb->postmeta.” invoice_number_meta539 on invoice_number_meta.post_id=wp_posts.ID and invoice_number_meta.meta_key=’REDNAO_WCPDFI_INVOICE_ID’540 “;541542 if($criteria=="InvoiceNumber”){543 $query.=$wpdb->prepare(' where invoice_number_meta.meta_value=%s’,$processor->GetRequired(‘InvoiceNumber’));544 }545546 if($criteria=="InvoiceDate”){547 $startDate=strtotime($processor->GetRequired(‘StartDate’));548 $endDate=strtotime($processor->GetRequired(‘EndDate’).’ +1 day’);549 $query.=$wpdb->prepare(' where invoice_date_meta.meta_value between %d and %d’,$startDate,$endDate);550 }551552 if($criteria=="OrderNumber”){553 $query.=$wpdb->prepare(' where wp_posts.ID=%s’,$processor->GetRequired(‘OrderNumber’));554 }555556557 $results=$wpdb->get_results($query,’ARRAY_A’);558559 foreach($results as &$result)560 {561 $result[‘Url’]=wp_specialchars_decode(get_edit_post_link($result[‘OrderNumber’]));562 $result[‘ViewUrl’]=wp_specialchars_decode(wp_nonce_url( admin_url( “admin-ajax.php?action=rednao_wcpdfinv_generate_pdf&orderid=” . $result[‘OrderNumber’] ), 'rednao_wcpdfinv_generate_pdf_’.$result[‘OrderNumber’] ));563564565 }566567 $processor->SendSuccessMessage($results);568 die();569 }570571 public function DontShowNewsletter(){572 update_option('pdfinvoice_newsletter’,2);573 $this->SendSuccessMessage(true);574 die();575 }576577 public function GetLatestError(){578 // register_shutdown_function(array($this, ‘CatchShutdownHandler’));579 echo get_option(‘PDFInvoiceErrorMessage’,’’);580 die();581 }582583 public function RemindMeLater(){584 $currentStage=get_option('wopdfinv_stage’,0);585 update_option('wopdfinv_stage’,$currentStage+1);586 }587588 public function DontShowAgain(){589 update_option(‘wopdfinv_stage’,4);590 $this->SendSuccessMessage(‘’);591 }592593 public function DiagnoseError(){594 register_shutdown_function( array($this,’ShutDownCatch’));595 set_error_handler(array($this, ‘CatchShutdownHandler’));596 delete_option(‘PDFInvoiceErrorMessage’);597 $invoiceId=$_POST[‘invoiceId’];598 require_once ‘PDFGenerator.php’;599 if($_POST[‘testType’]==’preview’){600601 $generator=new RednaoPDFGenerator(RednaoPDFGenerator::GetPageOptionsById($invoiceId),true,null);602603 }else{604 $orderNumber=$_POST[‘orderNumber’];605 $order=wc_get_order($orderNumber);606 if($order==false)607 {608 die();609 }else{610 $generator=new RednaoPDFGenerator(RednaoPDFGenerator::GetPageOptionsById($invoiceId),false,$order);611 }612613 }614615 $generator->GeneratePreview();616 die();617 }618619 public function ShutDownCatch(){620 if($this->detailCatched)621 return;622 $error = error_get_last();623 if( $error !== NULL) {624625626627 update_option('PDFInvoiceErrorMessage’,json_encode(array(628 "ErrorNumber"=>$error[“type”],629 "ErrorMessage"=>$error[“message”],630 "ErrorFile"=>$error[“file”],631 "ErrorLine"=>$error[“line”],632 "ErrorContext"=>"N/A",633 "Detail"=>"Unknown"634635 )));636 }637 }638639 public function CatchShutdownHandler($errorNumber, $errorStr,$errorFile,$errorLine){640 $this->detailCatched=true;641 $debug=json_encode(debug_backtrace());642643 update_option('PDFInvoiceErrorMessage’,json_encode(array(644 "ErrorNumber"=>$errorNumber,645 "ErrorMessage"=>$errorStr,646 "ErrorFile"=>$errorFile,647 "ErrorLine"=>$errorLine,648 "ErrorContext"=>null,649 "Detail"=>$debug650651 )));652 }653654 public function SaveCustomField(){655 $id=$this->GetStringValue('id’,true);656 $name=$this->GetStringValue('name’,true);657 $code=$this->GetStringValue('code’,true);658 $type=$this->GetStringValue('type’,true);659660 if(!is_super_admin())661 {662 $this->SendErrorMessage(‘Only admins can edit custom fields’);663 }664665 global $wpdb;666 if($id==0||$id==null)667 {668669 $result=$wpdb->insert(RednaoWooCommercePDFInvoice::$CUSTOM_FIELDS_TABLE,array(670 'custom_field_name’=>$name,671 'custom_field_text’=>$code,672 'custom_field_type’=>$type673 ));674 $rowId=$wpdb->insert_id;675 }else{676 $result=$wpdb->update(RednaoWooCommercePDFInvoice::$CUSTOM_FIELDS_TABLE,array(677 'custom_field_name’=>$name,678 ‘custom_field_text’=>$code,679 ‘custom_field_type’=>$type680 ),array(‘custom_field_id’=>$id));681 $rowId=$id;682 }683684 if($result===false)685 {686 $this->SendErrorMessage(‘Data could not be inserted’);687 }688 else689 {690 $this->SendSuccessMessage(array(‘row_id’ => $rowId));691 }692693 die();694 }695696 private function ProcessPostParameter()697 {698 if(!isset($_POST[‘data’]))699 throw new Exception(‘Invalid post parameters’);700701 $this->data=json_decode(stripslashes($_POST[‘data’]),true);702 if($this->data==null)703 throw new Exception(‘Invalid post parameters’);704 }705706 public function Export(){707 global $wpdb;708 if(!isset($_POST[‘pageId’]))709 {710 return;711 }712 $invoiceData=$wpdb->get_row("select extensions,conditions,attach_to,invoice_id,name,options,type,html,pages from “.RednaoWooCommercePDFInvoice::$INVOICE_TABLE.” where invoice_id=".$_POST[‘pageId’]);713 if($invoiceData==null){714 return;715 }716 $invoiceData->extensions=json_decode($invoiceData->extensions);717 $invoiceData->conditions=json_decode($invoiceData->conditions);718 $invoiceData->attach_to=json_decode($invoiceData->attach_to);719 $invoiceData->options=json_decode($invoiceData->options);720 $invoiceData->pages=json_decode($invoiceData->pages);721 $exporter=new \rnwcinv\ImportExport\TemplateExporter();722 $path=$exporter->Export($invoiceData);723724725726 header(“Content-Type: application/zip”);727 header("Content-Disposition: attachment; filename=".basename($path));728 header("Content-Length: " . filesize($path));729 readfile($path);730731 $exporter->Destroy();732 die();733 }734735 public function GetOptionalJsonValue($propertyName,$defaultValue=null)736 {737 if($this->data==null)738 $this->ProcessPostParameter();739740 if(!isset($this->data[$propertyName]))741 return $defaultValue;742743 return json_decode($this->data[$propertyName],true);744745 }746747748749750 public function GetJsonValue($propertyName)751 {752 if($this->data==null)753 $this->ProcessPostParameter();754755 return json_decode($this->data[$propertyName],true);756 }757758 public function GetDesignerPreview()759 {760 require_once(‘PDFPreview.php’);761 }762763 public function CheckIfOrderIsValid()764 {765 $orderId=$this->GetNumberValue(‘OrderNumber’);766 $post=get_post($orderId);767 if($post==null||$post->post_type!=’shop_order’)768 $this->SendErrorMessage(“Order Not Found”);769 /*if($post->post_status!=’wc-completed’)770 $this->SendErrorMessage(‘Order is not completed’);*/771 $this->SendSuccessMessage(‘success’);772 }773774 public function GetStringValue($propertyName,$required){775 if($this->data==null)776 $this->ProcessPostParameter();777778 if(!isset($this->data[$propertyName]))779 if($required)780 throw new Exception("Parameter not found ".$propertyName);781 else782 return ‘’;783784 return strval($this->data[$propertyName]);785 }786787 public function UpdateTemplate(){788 $this->Save();789 }790791 public function CreatePDF(){792793 if(!isset($_GET[‘orderid’])|| wp_verify_nonce($_GET[‘_wpnonce’], ‘rednao_wcpdfinv_generate_pdf_’.intval($_GET[‘orderid’]))==false){794 die(‘Forbidden’);795 }796797798 if(!isset($_GET[‘orderid’])||$_GET[‘orderid’]==’’)799 {800 echo "Invalid request, please try again";801 die();802 }803804 $actionid=’View’;805 if(isset($_GET[‘actionid’])&&($_GET[‘actionid’]==’View’||$_GET[‘actionid’]==’Download’))806 $actionid=strval($_GET[‘actionid’]);807808 $orderId=$_GET[‘orderid’];809810 $order=wc_get_order($orderId);811 if($order==false)812 {813 echo "Invalid Order Number";814 die();815 }else{816 $invoiceId=-1;817 if(isset($_GET[‘invoice_id’]))818 $invoiceId=$_GET[‘invoice_id’];819 require_once ‘PDFGenerator.php’;820821 $generator=\rnwcinv\GeneratorFactory::GetGenerator(RednaoPDFGenerator::GetOptionsForOrder($order,$invoiceId),$order);822 if($actionid==’View’)823 $generator->GeneratePreview(true);824 else825 {826 $generator->Generate();827 header(“Content-type: application/pdf”);828 header("Content-disposition: attachment; filename=".basename($generator->GetFileName()).’.pdf’);829 header(‘Expires: 0’);830 header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);831 echo $generator->GetOutput();832 }833 die();834 }835836837 }838839 public function GetNumberValue($propertyName, $required=false){840 if($this->data==null)841 $this->ProcessPostParameter();842843844 if($required&&!is_numeric($this->data[$propertyName]))845 throw new Exception("Invalid numeric parameter ".$propertyName);846 return intval($this->data[$propertyName]);847 }848849 public function GetBoolValue($propertyName, $required=false){850 if($this->data==null)851 $this->ProcessPostParameter();852853854 if($required&&!isset($this->data[$propertyName]))855 throw new Exception("Invalid numeric parameter ".$propertyName);856857 return $this->data[$propertyName]==true;858 }859860 public function GetArrayValue($propertyName)861 {862 if($this->data==null)863 $this->ProcessPostParameter();864865 if(!is_array($this->data[$propertyName]))866 return array();867868 return $this->data[$propertyName];869870 }871872873 public function GetFieldPreview(){874 $type=$this->GetStringValue(‘type’,false);875 $options=(object)$this->GetArrayValue(‘fieldOptions’);876877 /** @var FieldDTO $fieldOptions */878 $fieldOptions=new stdClass();879 $fieldOptions->type=’field’;880 $fieldOptions->fieldOptions=$options;881 $fieldOptions->fieldOptions->fieldType=$type;882 $field=FieldFactory::GetField($fieldOptions,new OrderValueRetriever(null,null,true,null,null));883884 if($fieldOptions->fieldOptions->fieldType==’inv_number’)885 {886 $additionalOptions=(object)$this->GetArrayValue(‘AdditionalOptions’);887 $formattedNumber=(new InvoiceInitialDataGenerator())->Create(0,0,(object)$additionalOptions->Format,true,new OrderValueRetriever(null,null,true,null,null));888 $this->SendSuccessMessage($formattedNumber->FormattedInvoiceNumber);889 }890 $this->SendSuccessMessage($field->FormatValue($field->GetFieldValue()));891892 }893894 public function Save(){895 $pageId=$this->GetNumberValue('pageId’,true);896 $pageType=$this->GetNumberValue('pageType’,true);897 $name=$this->GetStringValue('name’,true);898 $containerOptions=$this->GetStringValue('containerOptions’,true);899 $attachTo=$this->GetStringValue('attachTo’,true);900 $conditionOptions=$this->GetStringValue('conditions’,false);901 $pages=$this->GetStringValue('pages’,false);902 $createWhen=$this->GetStringValue('createWhen’,false);903 $originalExtensions=$this->GetJsonValue(‘extensions’);904 $myAccountDownload=$this->GetBoolValue('myAccountDownload’,true);905906907908 $orderActions=$this->GetOptionalJsonValue(‘orderActions’);909 if($orderActions!=null)910 $orderActions=json_encode($orderActions);911912 $extensions=json_encode(apply_filters('rnpdf_invoice_process_extensions_before_save’,$originalExtensions));913914 global $wpdb;915 $result=false;916 $rowId=0;917 $html=’’;918 if($pageId==0||$pageId==null)919 {920921922 $result=$wpdb->insert(RednaoWooCommercePDFInvoice::$INVOICE_TABLE,array(923 'name’=>$name,924 'options’=>$containerOptions,925 'type’=>$pageType,926 'options’=>$containerOptions,927 'attach_to’=>$attachTo,928 'extensions’=>$extensions,929 'conditions’=>$conditionOptions,930 'create_when’=>$createWhen,931 'order_actions’=>$orderActions,932 'pages’=>$pages,933 'html’=>$html,934 'my_account_download’=>$myAccountDownload935 ));936 $rowId=$wpdb->insert_id;937 }else{938 $result=$wpdb->update(RednaoWooCommercePDFInvoice::$INVOICE_TABLE,array(939 'name’=>$name,940 'options’=>$containerOptions,941 'type’=>$pageType,942 'options’=>$containerOptions,943 'pages’=>$pages,944 'attach_to’=>$attachTo,945 'order_actions’=>$orderActions,946 'extensions’=>$extensions,947 'create_when’=>$createWhen,948 'conditions’=>$conditionOptions,949 'my_account_download’=>$myAccountDownload,950 'html’=>$html951 ),array('invoice_id’=>$pageId));952 $rowId=$pageId;953 }954955 do_action('rnpdf_invoice_process_extensions_after_save’,array('pageId’=>$rowId,’extensions’=>$originalExtensions));956957 if($result===false)958 $this->SendErrorMessage('Data could not be inserted. Reason=’.$wpdb->last_error);959 else960 {961 update_option('REDNAO_PDF_INVOICE_EDITED’,true);962 $this->SendSuccessMessage(array(‘row_id’ => $rowId));963 }964 }965966967 public function SendSuccessMessage($data)968 {969 echo json_encode(array(970 'success’=>true,971 'result’=>$data)972 );973 die;974 }975976 public function SendErrorMessage($errorMessage)977 {978 echo json_encode(array(979 'success’=>false,980 'errorMessage’=>$errorMessage)981 );982 die;983 }984985986987988}989990new RednaoWooCommercePDFInvoiceAjax();991