Fatal error Call to undefined method VmVendorPDF::convertHTMLColorToDec()

Started by en92, October 11, 2013, 16:36:32 PM

Previous topic - Next topic

en92

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...


en92

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.

manue

hello,
i had the same issue
i solved it by updating vm aio

hope it helps

Vlad44b

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


Vlad44b

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.


stAn99

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, -55) == '<br/>') {
$this->vendorAddress substr($this->vendorAddress0, -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(=> array('h' => 0'n' => 0), => array('h' => 0'n' => 0)),
'div' => array(=> array('h' => 0'n' => 0), => array('h' => 0'n' => 0)),
'h1' => array(=> array('h' => 0'n' => 0), => array('h' => 0'n' => 0)),
'h2' => array(=> array('h' => 0'n' => 0), => array('h' => 0'n' => 0)),
'h3' => array(=> array('h' => 0'n' => 0), => array('h' => 0'n' => 0)),
'table' => array(=> array('h' => 0'n' => 0), => 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''falsefalse)."</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$border10true''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->$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->$this->$this->original_rMargin;
} else {
$this->$this->original_lMargin;
}
$header_x = (($this->getRTL())?($this->original_rMargin):($this->original_lMargin));
$cw $this->$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=*/2false/*$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->$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->$dx;
} else {
$x $dx;
}
$this->printTemplate($this->header_xobjid$x000''''false);
if ($this->header_xobj_autoreset) {
// reset header xobject template at each page
$this->header_xobjid false;
}
}

}

}




best regards, stan
----
RuposTel.com
www.rupostel.com
Your customized checkout solution for Virtuemart

Milbo

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.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/