Magento PDF Invoice Content Layout Issues - magento

I am not good with PDF's at all. I have added two secions below that are commented called "Invoice Comments and Order Comments". The trouble I am having is that I cannot put these two sections in a nice cell. When I try things like $pdf->Cell and etc. I just get the dreaded white screen. For some reason it seems that only drawText works with rendering the text. Also, the comments are extending off of the PDF page. I have tried to enter line breaks with no success. I guess its b/c the comments are Arrays. Any help would be great.
class Inchoo_Invoice_Model_Order_Pdf_Invoice extends Mage_Sales_Model_Order_Pdf_Invoice
{
protected function insertImage($image, $x1, $y1, $x2, $y2, $width, $height, &$page)
{
if (!is_null($image)) {
try{
$width = (int) $width;
$height = (int) $height;
//Get product image and resize it
$imagePath = Mage::helper('catalog/image')->init($image, 'image')
->keepAspectRatio(true)
->keepFrame(false)
->resize($width, $height)
->__toString();
$imageLocation = substr($imagePath,strlen(Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB)));
$image = Zend_Pdf_Image::imageWithPath($imageLocation);
//Draw image to PDF
$page->drawImage($image, $x1, $y1, $x2, $y2);
}
catch (Exception $e) {
return false;
}
}
}
public function getPdf($invoices = array())
{
$width = 1000;
$height = 1000;
$this->_beforeGetPdf();
$this->_initRenderer('invoice');
$pdf = new Zend_Pdf();
$this->_setPdf($pdf);
$style = new Zend_Pdf_Style();
$this->_setFontBold($style, 10);
foreach ($invoices as $invoice) {
if ($invoice->getStoreId()) {
Mage::app()->getLocale()->emulate($invoice->getStoreId());
}
$page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
$pdf->pages[] = $page;
$order = $invoice->getOrder();
/* Add image */
$this->insertLogo($page, $invoice->getStore());
/* Add address */
$this->insertAddress($page, $invoice->getStore());
/* Add head */
$page->drawText(Mage::helper('sales')->__('Invoice # ') . $invoice->getIncrementId(), 487, 780, 'UTF-8');
$this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID, $order->getStoreId()));
$page->setFillColor(new Zend_Pdf_Color_GrayScale(1));
$this->_setFontRegular($page);
/* Add table */
$page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
$page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
$page->setLineWidth(0.5);
$page->drawRectangle(25, $this->y, 570, $this->y -15);
$this->y -=10;
/* Add table head */
$page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
$page->drawText(Mage::helper('sales')->__('Products'), 35, $this->y, 'UTF-8');
//Added for product image
$page->drawText(Mage::helper('sales')->__('Product Image'), 279, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('SKU'), 125, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
$this->y -=15;
$page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
/* Add body */
foreach ($invoice->getAllItems() as $item){
if ($item->getOrderItem()->getParentItem()) {
continue;
}
if ($this->y < 15) {
$page = $this->newPage(array('table_header' => true));
}
/* Draw item */
$page = $this->_drawItem($item, $page, $order);
/* Draw product image */
$productId = $item->getOrderItem()->getProductId();
$image = Mage::getModel('catalog/product')->load($productId);
$this->insertImage($image, 345, (int)($this->y + 0), 275, (int)($this->y+65), $width, $height, $page);
}
/* Add totals */
$page = $this->insertTotals($page, $invoice);
/*************************** This Is The Invoice Comments ***********************************/
$_tempY = $this->y;
$this->y += 10;
$commentsCollection = $invoice->getCommentsCollection(true);
$internalcomments = "Internal Invoice Comments";
$page->drawText($internalcomments, 35, $this->y, 'UTF-8');
foreach($commentsCollection as $comm)
{
$page->drawText($comm->getData('comment'), 235, $this->y, 'UTF-8');
$this->y -= 10;
}
/*************************** End Invoice Comments ***********************************/
if ($invoice->getStoreId()) {
Mage::app()->getLocale()->revert();
}
}
/************************* This Is The Order Comments *******************************/
$_tempY = $this->y;
$this->y -= 80;
$statusHistoryCollection = $order->getStatusHistoryCollection();
$customersection = "Order Customer Comments";
$page->drawText($customersection, 35, $this->y, 'UTF-8');
foreach ($statusHistoryCollection as $statushistory) {
$page->drawText($statushistory->getComment(), 35, $this->y, 'UTF-8');
$this->y -= 10;
}
$this->y = $_tempY;
/************************* End Order Comments *******************************/
$this->_afterGetPdf();
return $pdf;
}
}

I have completed the Invoice Comments section for you so you'll be able to apply the same technique to the Order Comments. I tested this on my sandbox and it worked. You can change the value of 120 in the $textChunk = wordwrap($comm->getData('comment'), 120, "\n"); line to be whatever works best for your Invoice. I added a table header to the Internal Invoice Comments but you can remove that if you want.
/*************************** This Is The Invoice Comments ***********************************/
$this->_setFontRegular($page, 10);
// Begin table header
$page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
$page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
$page->setLineWidth(0.5);
$page->drawRectangle(25, $this->y, 570, $this->y -15);
$this->y -= 10;
$page->setFillColor(new Zend_Pdf_Color_RGB(0, 0, 0));
// end table header
$_tempY = $this->y;
$commentsCollection = $invoice->getCommentsCollection(true);
$internalcomments = "Internal Invoice Comments";
$page->drawText($internalcomments, 35, $this->y, 'UTF-8');
$this->y -= 15;
foreach($commentsCollection as $comm)
{
$textChunk = wordwrap($comm->getData('comment'), 120, "\n");
foreach(explode("\n", $textChunk) as $textLine){
if ($textLine!=='') {
$page->drawText(strip_tags(ltrim($textLine)), 35, $this->y, 'UTF-8');
$this->y -= 15;
}
}
}
/*************************** End Invoice Comments ***********************************/
P.S. Part of the new-line in Magento PDF routine was adapted from PHP + PDF Line Break. Thanks #shaune!

Related

Imagick php not printing hindi utf8 characters correctly

I have user imagick to printsome names from my mysql db to an image
$data = Common::getCandidatesForIdCard();
mkdir($data[0]['ulbRegion'], 0777, true);
for($i=0; $i<1; $i++) {
$image = new Imagick("image/img.jpeg");
$draw = new ImagickDraw();
/* Font properties */
$draw->setFont('fonts/MANGAL.TTF');
$draw->setFontSize(30);
$draw->setTextEncoding('UTF-8');
/* Create text */
$address = Common::getFormattedAddress($data[$i]['permanentAddress']);
$line1 = $address[0]." ".$address[1]." ".$address[2]." ".$address[3]." ".$address[4];
$line2 = $address[5]." ".$address[6]." ".$address[7]." ".$address[8]." ".$address[9];
$image->annotateImage($draw, 320, 740, 0, $data[$i]['name']);
$image->annotateImage($draw, 320, 840, 0, $data[$i]['guardian']);
$image->annotateImage($draw, 320, 940, 0, $line1);
$image->annotateImage($draw, 60, 1040, 0, $line2);
$image->annotateImage($draw, 320, 1140, 0, $data[$i]['ulbRegion']);
/* Give image a format */
$image->setImageFormat('png');
$image->minifyImage();
header('Content-type: image/png');
file_put_contents($data[0]['ulbRegion']."/imagick_ouput_".$i.".png" , $image);
}
But the issue is the text on the image is not printing correctly ....
i.e instead of अमित it is printing अमति

Magento get attribule value on pdf invoice

I try to get a product attribute value on my invoice, but everything i tried found on stack doesn't give a result (getdata, getattribute, getressouce...)
Below is an extract of the file, i would like to replace the last line "getname" by getattribute
Thanks a lot
$order = $this->getOrder();
$item = $this->getItem();
$pdf = $this->getPdf();
$page = $this->getPage();
//$lines = array();
//if not only checking the height - let's check and set up page and background if needed
if (!$returnHeight)
{
$blockHeight = $this->draw(true);
if ($pdf->y - $blockHeight < 12)
{
$page = $pdf->newPage(array('table_header' => true));
$this->setPage($page);
}
if ($pdf->currentItemWithBg)
{
$page -> setFillColor(new Zend_Pdf_Color_Html('#' . $pdf -> params['lightBg']));
$page -> drawRectangle(18, $pdf -> y, $page->getWidth() - 18, $pdf -> y - $blockHeight, $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL);
}
}
//get price and subtotal values
$prices = $this->getItemPricesForDisplay();
$topOffset = 10;
//if there are labels leave more space at the top
if (count($prices) > 0 && !empty($prices[0]['label']))
$topOffset = 16;
//slice product name into chunks
$font = $pdf->_setFontLight($page, 9);
$nameParts = $commonHelper->sliceStringByPoints($item->getName(), 191, $font, 9);

GD blurry images Opencart

I have this problem with GD image processing in Opencart that creates real bad blurry images after resize. Nothing I have tried so far has helped.
Below is the code for the image.php
<?php
class Image {
private $file;
private $image;
private $info;
public function __construct($file) {
if (file_exists($file)) {
$this->file = $file;
$info = getimagesize($file);
$this->info = array(
'width' => $info[0],
'height' => $info[1],
'bits' => $info['bits'],
'mime' => $info['mime']
);
$this->image = $this->create($file);
} else {
exit('Error: Could not load image ' . $file . '!');
}
}
private function create($image) {
$mime = $this->info['mime'];
if ($mime == 'image/gif') {
return imagecreatefromgif($image);
} elseif ($mime == 'image/png') {
return imagecreatefrompng($image);
} elseif ($mime == 'image/jpeg') {
return imagecreatefromjpeg($image);
}
}
public function save($file, $quality = 100) {
$info = pathinfo($file);
$extension = strtolower($info['extension']);
if (is_resource($this->image)) {
if ($extension == 'jpeg' || $extension == 'jpg') {
imagejpeg($this->image, $file, $quality);
} elseif($extension == 'png') {
imagepng($this->image, $file);
} elseif($extension == 'gif') {
imagegif($this->image, $file);
}
imagedestroy($this->image);
}
}
/**
*
* #param width
* #param height
* #param default char [default, w, h]
* default = scale with white space,
* w = fill according to width,
* h = fill according to height
*
*/
public function resize($width = 0, $height = 0, $default = '') {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h'){
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png')
{
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $height);
if (isset($this->info['mime']) && $this->info['mime'] == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width,
$new_height, $this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $width;
$this->info['height'] = $height;
}
public function watermark($file, $position = 'bottomright') {
$watermark = $this->create($file);
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
switch($position) {
case 'topleft':
$watermark_pos_x = 0;
$watermark_pos_y = 0;
break;
case 'topright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = 0;
break;
case 'bottomleft':
$watermark_pos_x = 0;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
case 'bottomright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
}
imagecopy($this->image, $watermark,
$watermark_pos_x, $watermark_pos_y, 0, 0, 120, 40);
imagedestroy($watermark);
}
public function crop($top_x, $top_y, $bottom_x, $bottom_y) {
$image_old = $this->image;
$this->image = imagecreatetruecolor($bottom_x - $top_x, $bottom_y - $top_y);
imagecopy($this->image, $image_old, 0, 0, $top_x, $top_y,
$this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $bottom_x - $top_x;
$this->info['height'] = $bottom_y - $top_y;
}
public function rotate($degree, $color = 'FFFFFF') {
$rgb = $this->html2rgb($color);
$this->image = imagerotate($this->image, $degree,
imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
$this->info['width'] = imagesx($this->image);
$this->info['height'] = imagesy($this->image);
}
private function filter($filter) {
imagefilter($this->image, $filter);
}
private function text($text, $x = 0, $y = 0, $size = 5, $color = '000000') {
$rgb = $this->html2rgb($color);
imagestring($this->image, $size, $x, $y, $text,
imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
}
private function merge($file, $x = 0, $y = 0, $opacity = 100) {
$merge = $this->create($file);
$merge_width = imagesx($image);
$merge_height = imagesy($image);
imagecopymerge($this->image, $merge, $x, $y, 0, 0, $merge_width,
$merge_height, $opacity);
}
private function html2rgb($color) {
if ($color[0] == '#') {
$color = substr($color, 1);
}
if (strlen($color) == 6) {
list($r, $g, $b) = array($color[0] . $color[1], $color[2] . $color[3],
$color[4] . $color[5]);
} elseif (strlen($color) == 3) {
list($r, $g, $b) = array($color[0] . $color[0], $color[1] . $color[1],
$color[2] . $color[2]);
} else {
return false;
}
$r = hexdec($r);
$g = hexdec($g);
$b = hexdec($b);
return array($r, $g, $b);
}
}
?>
As you can see the quality is already set to 100 , so that doesn't help.
I have tried replacing resize with resample - but that produced no visible result.
However I have found this suggestion (code below) to sharpen images, unfortunately I am not sure how and where to use it. Especially since original code processed multiple image types. Please help to put this in the right place.
{
$matrix = array(
array(-1, -1, -1),
array(-1, 16, -1),
array(-1, -1, -1),
);
$divisor = array_sum(array_map('array_sum', $matrix));
$offset = 0;
imageconvolution($image, $matrix, $divisor, $offset);
return $image;
}
Also, if you have other suggestions to improve this code, help is greatly appreciated! I think that goes for the whole Opencart community, as this has been discussed many time but no working solution posted as of yet.
The quality parameter will only be applicable to .jpeg images.
To sharpen the images you could apply the imageconvolution() code within the resize() function.
public function resize($width = 0, $height = 0, $default = '') {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h') {
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png') {
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $height);
if (isset($this->info['mime']) && $this->info['mime'] == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width, $new_height, $this->info['width'], $this->info['height']);
//Image Sharpening Code
$matrix = array(
array(0.0, -1.0, 0.0),
array(-1.0, 5.0, -1.0),
array(0.0, -1.0, 0.0)
);
$divisor = array_sum(array_map('array_sum', $matrix));
$offset = 0;
imageconvolution($this->image, $matrix, $divisor, $offset);
// End Image Sharpening Code
imagedestroy($image_old);
$this->info['width'] = $width;
$this->info['height'] = $height;
}
References:
sharpen image quality with PHP gd library
http://adamhopkinson.co.uk/blog/2010/08/26/sharpen-an-image-using-php-and-gd/

Magento add price and color in meta description

I would like to add product price in meta description of products. I don't write meta desc in product options, magento gets it from product desc. (it's ok to me)
$description = $product->getMetaDescription();
if ($description) {
$headBlock->setDescription( ($description) );
} else {
$headBlock->setDescription(Mage::helper('core/string')->substr($product->getDescription(), 0, 255));
How to make Meta desc looks like that= ProductDesc Color only FinalPrice
?
Pleas copyfile view.php app\code\core\Mage\Catalog\Block\Product to app\code\local\Mage\Catalog\Block\Product
here find protected function _prepareLayout()
find code and comment this
$description = $product->getMetaDescription();
if ($description) {
$headBlock->setDescription( ($description) );
} else {
$headBlock->setDescription(Mage::helper('core/string')->substr($product->getDescription(), 0, 255));
}
And try below
$Color=$product->getAttributeText('color');
$baseCurrencyCode = Mage::app()->getStore()->getBaseCurrencyCode();
$currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$currencySymbol = Mage::app()->getLocale()->currency($currentCurrencyCode)->getSymbol();
$price=$currentCurrencyCode .' '.Mage::helper('core')->currency($product->getFinalPrice(),false,true);
$metaTmp1=$Color.' only '. $price;
$strlen=strlen($metaTmp);
$metaTmp2==Mage::helper('core/stri;ng')->substr($product->getDescription(), 0, (255-$strlen-5));
$meta= $metaTmp2.''.$metaTmp1;
$headBlock->setDescription( $meta) ;
So I did:
//$headBlock->setDescription(Mage::helper('core/string')->substr($product->getDescription(),
0, 255)); $Color=$product->getAttributeText('color');
$baseCurrencyCode = Mage::app()->getStore()->getBaseCurrencyCode();
$currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$currencySymbol = Mage::app()->getLocale()->currency($currentCurrencyCode)->getSymbol();
$price=$currentCurrencyCode .' '.Mage::helper('core')->currency($product->getFinalPrice(),false,true);
$metaTmp1=$Color.' only '. $price;
$strlen=strlen($metaTmp);
$metaTmp2==Mage::helper('core/string')->substr($product->getDescription(),
0, (255-$strlen-5));
$meta= $metaTmp2.''.$metaTmp1;
$headBlock->setDescription( $meta) ; }
And in HTML code, in Meta desc I see only f ex " only 123" - so the price only.
No I don't need to manage it from admin.

Session always store the previous value

I'm developing a email sending form. It has a captcha security image. When ever I refresh the image to load new captcha it always stores the previous session value. It never stores the correct one.
But in my localhost it works fine. Thank you very much.
class CaptchaSecurityImages {
var $font = 'monofont.ttf';
function generateCode($characters) {
/* list all possible characters, similar looking characters and vowels have been removed */
$possible = '23456789bcdfghjkmnpqrstvwxyz';
$code = '';
$i = 0;
while ($i < $characters) {
$code .= substr($possible, mt_rand(0, strlen($possible)-1), 1);
$i++;
}
$_SESSION['securitycode'] = $code;
return $code;
}
function CaptchaSecurityImages($width='120',$height='40',$characters='6') {
$code = $this->generateCode($characters);
/* font size will be 75% of the image height */
$_SESSION['securitycode'] = $code;
$font_size = $height * 0.75;
$image = #imagecreate($width, $height) or die('Cannot initialize new GD image stream');
/* set the colours */
$background_color = imagecolorallocate($image, 255, 255, 255);
$text_color = imagecolorallocate($image, 20, 40, 100);
$noise_color = imagecolorallocate($image, 100, 120, 180);
/* generate random dots in background */
for( $i=0; $i<($width*$height)/3; $i++ ) {
imagefilledellipse($image, mt_rand(0,$width), mt_rand(0,$height), 1, 1, $noise_color);
}
/* generate random lines in background */
for( $i=0; $i<($width*$height)/150; $i++ ) {
imageline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color);
}
/* create textbox and add text */
$textbox = imagettfbbox($font_size, 0, $this->font, $code) or die('Error in imagettfbbox function');
$x = ($width - $textbox[4])/2;
$y = ($height - $textbox[5])/2;
imagettftext($image, $font_size, 0, $x, $y, $text_color, $this->font , $code) or die('Error in imagettftext function');
/* output captcha image to browser */
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
}
}
This is the class I'm using to generate captcha.

Resources