hi all,
joomla 2.5.9
virtuemart 2.0.24
it has to do with the creation of pdf invoices, I did not have this problem yet when I did not have the safe path configured yet. I set up of the safe path according to the other post on this forum...
the error occurs on checkout, i set the send the pdf to be send on pending and confirmed, I changed it to only confirmed but it did not resolve the issue. The full error message reads:Fatal error: Call to undefined method VmVendorPDF::convertHTMLColorToDec() in /domains/xxx/DEFAULT/components/com_virtuemart/helpers/vmpdf.php on line 111
I dont have a live site yet
any help would be appreciated
and yes I have checked all the forum message there are no solutions already posted ;-)
could it have something to do with tcpdf, or with the setup of the shop?
thanks a lot and sorry if the message is in the wrong place or there is not enough info...
and php 5.3
Sorry to keep on replying instead of posting one coherent post but I keep finding out stuff. When I deleted my test orders I got this error message:
vmError: TableInvoices The given COM_VIRTUEMART_INVOICE_NUMBER is empty. This field is obligatory, please enter your data and store again.
hello,
i had the same issue
i solved it by updating vm aio
hope it helps
Quote from: en92 on October 11, 2013, 16:56:58 PM
Sorry to keep on replying instead of posting one coherent post but I keep finding out stuff. When I deleted my test orders I got this error message:
vmError: TableInvoices The given COM_VIRTUEMART_INVOICE_NUMBER is empty. This field is obligatory, please enter your data and store again.
hello,
I had the same issue:
When I deleted my test orders I got this error message:
vmError: TableInvoices COM_VIRTUEMART_INVOICE_NUMBER empty.
VM 2.0.24b
aio 2.0.24b
PHP 5.3.3
Joomla 2.5.17
VM 2.0.26
AIO 2.0.26
PHP version: http://phpinfo-new.um.la
My error still persists.
When I deleted my orders I got error message:
vmError: TableInvoices COM_VIRTUEMART_INVOICE_NUMBER is empty.
This field is required, please enter your details.
virtuemart 3.0.12 latest stable
this issue is still not fixed and Virtuemart should check if the fucntion which it tries to trigger ON DEFAULT CONFIGURATION do really exists.
USER SOLUTION:
the issue can be probably fixed by reinstalling tcpdf library from Virtuemart download section but when using various 3rd parties tcpdf library it's questionable if it would solve the problem (since each 3rd party uses a different version of tcpdf)
generally the problem can be fixed by creating a new Order status "NO_PDF" and associate the Invoice creation to this NO_PDF order status which would never be reached.
the problem on vm3.0.12 that i've seen at our customer is that we did not receive a blank page, but the customer emails were just not sent... without knowing there is such a fatal error on the site.
CORE SUGGESTION
1. important -> remove class declaration from within the IF statement since it's NOT OPCODE COMPATIBLE and may cause lot's of huge issues on busy sites with opcode cache
2. add method_exists to all tcpdf functions since it seems that their API changes often and it's being used by 3rd parties in /libraries/tcpdf quite often
suggest update (not tested):
1. adds method exists the most commontly missing function
2. adds public $error variable which if it's set to true, returns no pdf
<?php
defined('_JEXEC') or die('');
/**
* abstract controller class containing get,store,delete,publish and pagination
*
*
* This class provides the functions for the calculatoins
*
* @package VirtueMart
* @subpackage Helpers
* @author Max Milbers
* @copyright Copyright (c) 2011 - 2014 VirtueMart Team. All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
*
* http://virtuemart.net
*/
defined('DS') or define('DS', DIRECTORY_SEPARATOR);
if (!class_exists( 'VmConfig' )) require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');
VmConfig::loadConfig();
if(!class_exists('VmModel')) require(VMPATH_ADMIN.DS.'helpers'.DS.'vmmodel.php');
if(!class_exists('VmImage')) require(VMPATH_ADMIN.DS.'helpers'.DS.'image.php');
class VmPdf {
/** Function to create a nice vendor-styled PDF for the output of the given view.
The $path and $dest arguments are directly passed on to TCPDF::Output.
To create a PDF directly from a given HTML (i.e. not through a view), one
can directly use the VmVendorPDF class, see VirtueMartControllerInvoice::samplePDF */
static function createVmPdf($view, $path='', $dest='F', $meta=array()) {
if(!$view){
// TODO: use some default view???
return;
}
if(!class_exists('VmVendorPDF')){
vmError('vmPdf: For the pdf, you must install the tcpdf library at '.VMPATH_LIBS.DS.'tcpdf');
return 0;
}
$pdf = new VmVendorPDF();
if (!empty($pdf->error)) return;
if (isset($meta['title'])) $pdf->SetTitle($meta['title']);
if (isset($meta['subject'])) $pdf->SetSubject($meta['subject']);
if (isset($meta['keywords'])) $pdf->SetKeywords($meta['keywords']);
// Make the formatter available, just in case some specialized view wants/needs it
$view->pdf_formatter = $pdf;
$view->isPdf = true;
$view->print = false;
ob_start();
$view->display();
$html = ob_get_contents();
ob_end_clean();
$pdf->AddPage();
$pdf->PrintContents($html);
// Close and output PDF document
// This method has several options, check the source code documentation for more information.
$pdf->Output($path, $dest);
return $path;
}
}
if(!file_exists(VMPATH_LIBS.DS.'tcpdf'.DS.'tcpdf.php')){
vmError('VmPDF helper: For the PDF invoice and other PDF business letters, you must install the tcpdf library at '.VMPATH_LIBS.DS.'tcpdf');
} else {
if(!class_exists('TCPDF'))require(VMPATH_LIBS.DS.'tcpdf'.DS.'tcpdf.php');
// Extend the TCPDF class to create custom Header and Footer as configured in the Backend
class VmVendorPDF extends TCPDF {
var $vendor = 0;
var $vendorImage = '';
var $vendorAddress = '';
var $css = '';
var $virtuemart_vendor_id = 1;
var $tcpdf6 = false;
var $error = false;
public function __construct() {
// Load the vendor, so we have the data for the header/footer...
// The images are NOT loaded by default, so do it manually, just in case
$vendorModel = VmModel::getModel('vendor');
$this->vendor = $vendorModel->getVendor($this->virtuemart_vendor_id);
$vendorModel->addImages($this->vendor,1);
$this->vendor->vendorFields = $vendorModel->getVendorAddressFields($this->virtuemart_vendor_id);
parent::__construct($this->vendor->vendor_letter_orientation, 'mm', $this->vendor->vendor_letter_format);
$this->css = $this->vendor->vendor_letter_css;
// set document information
$this->SetCreator(vmText::_('COM_VIRTUEMART_PDF_CREATOR'));
if(empty($this->vendor->images[0])){
vmError('Vendor image given path empty ');
} else if(empty($this->vendor->images[0]->file_url_folder) or empty($this->vendor->images[0]->file_name) or empty($this->vendor->images[0]->file_extension) ){
vmError('Vendor image given image is not complete '.$this->vendor->images[0]->file_url_folder.$this->vendor->images[0]->file_name.'.'.$this->vendor->images[0]->file_extension);
} else if(!empty($this->vendor->images[0]->file_extension) and strtolower($this->vendor->images[0]->file_extension)=='png'){
vmError('Warning extension of the image is a png, tpcdf has problems with that in the header, choose a jpg or gif');
} else {
$imagePath = str_replace('/',DS, $this->vendor->images[0]->file_url_folder.$this->vendor->images[0]->file_name.'.'.$this->vendor->images[0]->file_extension);
if(!file_exists(VMPATH_ROOT . DS . $imagePath)){
vmError('Vendor image missing '.$imagePath);
} else {
$this->vendorImage=$imagePath;
}
}
// Generate PDF header
if (!class_exists ('JFile')) {
require(VMPATH_LIBS . DS . 'joomla' . DS . 'filesystem' . DS . 'file.php');
}
$this->tcpdf6 = JFile::exists(VMPATH_LIBS.DS.'tcpdf'.DS.'include'.DS.'tcpdf_colors.php');
if($this->tcpdf6){
$this->tcpdf6 = method_exists('TCPDF','getAllSpotColors');
}
if($this->tcpdf6){
$getAllSpotColors = TCPDF::getAllSpotColors();
if (!method_exists('TCPDF_COLORS', 'convertHTMLColorToDec')) {
$this->error = true;
return true;
}
$vlfooterlcolor = TCPDF_COLORS::convertHTMLColorToDec($this->vendor->vendor_letter_footer_line_color,$getAllSpotColors);
} else {
if (!method_exists($this, 'convertHTMLColorToDec')) {
$this->error = true;
return true;
}
$vlfooterlcolor = $this->convertHTMLColorToDec($this->vendor->vendor_letter_footer_line_color);
}
$this->setHeaderData(($this->vendor->vendor_letter_header_image?$this->vendorImage:''),
($this->vendor->vendor_letter_header_image?$this->vendor->vendor_letter_header_imagesize:0),
'', $this->vendor->vendor_letter_header_html,
array(0,0,0),$vlfooterlcolor );
$this->vendorAddress = shopFunctionsF::renderVendorAddress($this->vendor->virtuemart_vendor_id, "<br/>");
// Trim the final <br/> from the address, which is inserted by renderVendorAddress automatically!
if (substr($this->vendorAddress, -5, 5) == '<br/>') {
$this->vendorAddress = substr($this->vendorAddress, 0, -5);
}
$vmFont=$this->vendor->vendor_letter_font;
try {
$this->SetFont($vmFont, '', $this->vendor->vendor_letter_font_size, '', 'false');
$this->setHeaderFont(Array($vmFont, '', $this->vendor->vendor_letter_header_font_size ));
$this->setFooterFont(Array($vmFont, '', $this->vendor->vendor_letter_footer_font_size ));
}
catch (Exception $e)
{
// the font is not installed
}
// Remove all vertical margins and padding from the HTML cells (default is excessive padding):
$this->SetCellPadding(0);
$tagvs = array('p' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n' => 0)),
'div' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n' => 0)),
'h1' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n' => 0)),
'h2' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n' => 0)),
'h3' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n' => 0)),
'table' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n' => 0)),
);
$this->setHtmlVSpace($tagvs);
// set default font subsetting mode
$this->setFontSubsetting(true);
// set default monospaced font
// $this->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
//set margins
$this->SetMargins($this->vendor->vendor_letter_margin_left, $this->vendor->vendor_letter_margin_top, $this->vendor->vendor_letter_margin_right);
$this->SetHeaderMargin($this->vendor->vendor_letter_margin_header);
$this->SetFooterMargin($this->vendor->vendor_letter_margin_footer);
$this->SetAutoPageBreak(TRUE, $this->vendor->vendor_letter_margin_bottom);
//set image scale factor
$this->setImageScale(PDF_IMAGE_SCALE_RATIO);
//TODO include the right file (in libraries/tcpdf/config/lang set some language-dependent strings
$l='';
$this->setLanguageArray($l);
}
/** Replace variables like {vm:page}, {vm:pagecount} etc. in the given string
*/
function replace_variables($txt) {
// TODO: Implement more Placeholders (ordernr, invoicenr, etc.)
// Use PageNo rather than getAliasNumPage, since the alias will be misaligned (spaced like the {:npn:} text rather than the final number)
$txt = str_replace('{vm:pagenum}', $this->/*getAliasNumPage*/PageNo(), $txt);
// Can't use getNumPages, because when this is evaluated, we don't know the final number of pages (getNumPages is always equal to the current page numbe)
$txt = str_replace('{vm:pagecount}', $this->getAliasNbPages/*getNumPages*/(), $txt);
$txt = str_replace('{vm:vendorname}', $this->vendor->vendor_store_name, $txt);
$imgrepl='';
if (!empty($this->vendor->images)) {
$img = $this->vendor->images[0];
$imgrepl = "<div class=\"vendor-image\">".$img->displayIt($img->file_url,'','',false, '', false, false)."</div>";
}
$txt = str_replace('{vm:vendorimage}', $imgrepl, $txt);
$txt = str_replace('{vm:vendoraddress}', $this->vendorAddress, $txt);
$txt = str_replace('{vm:vendorlegalinfo}', $this->vendor->vendor_legal_info, $txt);
$txt = str_replace('{vm:vendordescription}', $this->vendor->vendor_store_desc, $txt);
$txt = str_replace('{vm:tos}', $this->vendor->vendor_terms_of_service, $txt);
return "$txt";
}
public function PrintContents($html) {
$contents = $this->replace_variables ($html);
$this->writeHTMLCell($w=0, $h=0, $x='', $y='', $contents, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true);
}
public function Footer() {
if ($this->vendor->vendor_letter_footer == 1) {
$footertxt = '<style>' . $this->css . '</style>';
$footertxt .= '<div id="vmdoc-footer" class="vmdoc-footer">' . $this->replace_variables($this->vendor->vendor_letter_footer_html) . '</div>';
$currentCHRF = $this->getCellHeightRatio();
$this->setCellHeightRatio($this->vendor->vendor_letter_footer_cell_height_ratio);
if (!class_exists ('JFile')) {
require(VMPATH_LIBS . DS . 'joomla' . DS . 'filesystem' . DS . 'file.php');
}
$this->tcpdf6 = JFile::exists(VMPATH_LIBS.DS.'tcpdf'.DS.'include'.DS.'tcpdf_colors.php');
if($this->tcpdf6){
$this->tcpdf6 = method_exists('TCPDF','getAllSpotColors');
}
if($this->tcpdf6){
$getAllSpotColors = TCPDF::getAllSpotColors();
$vlfooterlcolor = TCPDF_COLORS::convertHTMLColorToDec($this->vendor->vendor_letter_footer_line_color,$getAllSpotColors);
} else {
$vlfooterlcolor = $this->convertHTMLColorToDec($this->vendor->vendor_letter_footer_line_color);
}
//set style for cell border
$border = 0;
if ($this->vendor->vendor_letter_footer_line == 1) {
$line_width = 0.85 / $this->getScaleFactor();
$this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $vlfooterlcolor));
$border = 'T';
}
// TODO: Implement cell_height
// $cell_height = round(($this->getCellHeightRatio() * $footerfont[2]) / $this->getScaleFactor(), 2);
$cell_height=1;
$this->writeHTMLCell(0, $cell_height, '', '', $footertxt, $border, 1, 0, true, '', true);
// Set it back
$this->setCellHeightRatio($currentCHRF);
}
}
public function Header() {
if ($this->vendor->vendor_letter_header != 1) return;
if ($this->header_xobjid === false) {
// start a new XObject Template
$this->header_xobjid = $this->startTemplate($this->w, $this->tMargin);
$headerfont = $this->getHeaderFont();
$headerdata = $this->getHeaderData();
$this->y = $this->header_margin;
$headertxt = '<style>' . $this->css . '</style>';
$headertxt .= '<div id="vmdoc-header" class="vmdoc-header">' . $this->replace_variables($headerdata['string']) . '</div>';
$currentCHRF = $this->getCellHeightRatio();
$this->setCellHeightRatio($this->vendor->vendor_letter_header_cell_height_ratio);
if ($this->rtl) {
$this->x = $this->w - $this->original_rMargin;
} else {
$this->x = $this->original_lMargin;
}
$header_x = (($this->getRTL())?($this->original_rMargin):($this->original_lMargin));
$cw = $this->w - $this->original_lMargin - $this->original_rMargin;
if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
if (!class_exists ('JFile')) {
require(VMPATH_LIBS . DS . 'joomla' . DS . 'filesystem' . DS . 'file.php');
}
$this->tcpdf6 = JFile::exists(VMPATH_LIBS.DS.'tcpdf'.DS.'include'.DS.'tcpdf_images.php');
if($this->tcpdf6){
if (!class_exists ('TCPDF_IMAGES')) {
require(VMPATH_LIBS.DS.'tcpdf'.DS.'include'.DS.'tcpdf_images.php');
}
$imgtype = TCPDF_IMAGES::getImageFileType(VMPATH_ROOT.DS.$headerdata['logo']);
} else {
$imgtype = $this->getImageFileType(VMPATH_ROOT.DS.$headerdata['logo']);
}
if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
$this->ImageEps(VMPATH_ROOT.DS.$headerdata['logo'], '', '', $headerdata['logo_width']);
} elseif ($imgtype == 'svg') {
$this->ImageSVG(VMPATH_ROOT.DS.$headerdata['logo'], '', '', $headerdata['logo_width']);
} else {
$this->Image(VMPATH_ROOT.DS.$headerdata['logo'], '', '', $headerdata['logo_width']);
}
$imgy = $this->getImageRBY();
$header_x += ($headerdata['logo_width'] * 1.1);
$cw -= ($headerdata['logo_width'] * 1.1);
} else {
$imgy = $this->y;
}
// set starting margin for text data cell
$this->SetTextColorArray($this->header_text_color);
// header string
$this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
$this->SetX($header_x);
$this->writeHTMLCell($cw, /*$cell_height*/0, $this->x, $this->header_margin, $headertxt, '', /*$ln=*/2, false, /*$reseth*/true, '', /*$autopadding=*/true);
// print an ending header line
if ($this->vendor->vendor_letter_header_line == 1) {
$this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $headerdata['line_color']));
$this->SetY(max($imgy,$this->y));
if ($this->rtl) {
$this->SetX($this->original_rMargin);
} else {
$this->SetX($this->original_lMargin);
}
$this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C');
}
$this->setCellHeightRatio($currentCHRF);
$this->endTemplate();
}
// print header template
$x = 0;
$dx = 0;
if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
// adjust margins for booklet mode
$dx = ($this->original_lMargin - $this->original_rMargin);
}
if ($this->rtl) {
$x = $this->w + $dx;
} else {
$x = 0 + $dx;
}
$this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
if ($this->header_xobj_autoreset) {
// reset header xobject template at each page
$this->header_xobjid = false;
}
}
}
}
best regards, stan
Quote from: stAn99 on February 25, 2016, 13:56:48 PM
USER SOLUTION:
the issue can be probably fixed by reinstalling tcpdf library from Virtuemart download section but when using various 3rd parties tcpdf library it's questionable if it would solve the problem (since each 3rd party uses a different version of tcpdf)
It is not questionable, because we just replaced a very outdated version, with the new one (and is also already outdated of course).
Why does it happen? I removed the tcpdf from the Aio, years ago. The new version does not fit within the AIO, so it has an own installer now. Since then, you must update tcpdf yourself, when you update vm2.0,...but it is then an own component and you get informed by the joomla update notification system. The Tcpdf is provided in any download package, so it is not a problem for anyone who already started with the new package, only for updaters.
So an update with the last http://dev.virtuemart.net/projects/tcpdf/files should be enough.
Quote from: stAn99 on February 25, 2016, 13:56:48 PM
generally the problem can be fixed by creating a new Order status "NO_PDF" and associate the Invoice creation to this NO_PDF order status which would never be reached.
the problem on vm3.0.12 that i've seen at our customer is that we did not receive a blank page, but the customer emails were just not sent... without knowing there is such a fatal error on the site.
http://docs.virtuemart.net/manual/general-concepts/205-invoices.html
Quote from: stAn99 on February 25, 2016, 13:56:48 PM
since it seems that their API changes often
From my point of view, he changed 2 functions calls within 6 years, that is not often.