dolibarr  7.0.0-beta
barcode.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2004-2010 Folke Ashberg: Some lines of code were inspired from work
4  * of Folke Ashberg into PHP-Barcode 0.3pl2, available as GPL
5  * source code at http://www.ashberg.de/bar.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
27 /* ******************************************************************** */
28 /* COLORS */
29 /* ******************************************************************** */
30 $bar_color=array(0,0,0);
31 $bg_color=array(255,255,255);
32 $text_color=array(0,0,0);
33 
34 
35 /* ******************************************************************** */
36 /* FONT FILE */
37 /* ******************************************************************** */
38 if (defined('DOL_DEFAULT_TTF_BOLD')) $font_loc=constant('DOL_DEFAULT_TTF_BOLD');
39 // Automatic-Detection of Font if running Windows
40 // @CHANGE LDR
41 if (isset($_SERVER['WINDIR']) && @file_exists($_SERVER['WINDIR'])) $font_loc=$_SERVER['WINDIR'].'\Fonts\arialbd.ttf';
42 if (empty($font_loc)) die('DOL_DEFAULT_TTF_BOLD must de defined with full path to a TTF font.');
43 
44 
45 /* ******************************************************************** */
46 /* GENBARCODE */
47 /* ******************************************************************** */
48 /* location of 'genbarcode'
49  * leave blank if you don't have them :(
50 * genbarcode is needed to render encodings other than EAN-12/EAN-13/ISBN
51 */
52 
53 if (defined('PHP-BARCODE_PATH_COMMAND')) $genbarcode_loc=constant('PHP-BARCODE_PATH_COMMAND');
54 else $genbarcode_loc = $conf->global->GENBARCODE_LOCATION;
55 
56 
57 
58 
68 function barcode_print($code, $encoding="ANY", $scale = 2 ,$mode = "png")
69 {
70  dol_syslog("barcode.lib.php::barcode_print $code $encoding $scale $mode");
71 
72  $bars=barcode_encode($code,$encoding);
73  if (! $bars || ! empty($bars['error']))
74  {
75  // Return error message instead of array
76  if (empty($bars['error'])) $error='Bad Value '.$code.' for encoding '.$encoding;
77  else $error=$bars['error'];
78  dol_syslog('barcode.lib.php::barcode_print '.$error, LOG_ERR);
79  return $error;
80  }
81  if (! $mode) $mode="png";
82  //if (preg_match("/^(text|txt|plain)$/i",$mode)) print barcode_outtext($bars['text'],$bars['bars']);
83  //elseif (preg_match("/^(html|htm)$/i",$mode)) print barcode_outhtml($bars['text'],$bars['bars'], $scale,0, 0);
84  //else
85  barcode_outimage($bars['text'], $bars['bars'], $scale, $mode);
86  return $bars;
87 }
88 
111 function barcode_encode($code,$encoding)
112 {
113  global $genbarcode_loc;
114 
115  if (
116  (preg_match("/^ean$/i", $encoding))
117 
118  || (($encoding) && (preg_match("/^isbn$/i", $encoding))
119  && (( strlen($code)==9 || strlen($code)==10) ||
120  (((preg_match("/^978/", $code) && strlen($code)==12) ||
121  (strlen($code)==13)))))
122 
123  || (( !isset($encoding) || !$encoding || (preg_match("/^ANY$/i", $encoding) ))
124  && (preg_match("/^[0-9]{12,13}$/", $code)))
125  )
126  {
127  /* use built-in EAN-Encoder */
128  dol_syslog("barcode.lib.php::barcode_encode Use barcode_encode_ean");
129  $bars=barcode_encode_ean($code, $encoding);
130  }
131  else if (file_exists($genbarcode_loc)) // For example C39
132  {
133  /* use genbarcode */
134  dol_syslog("barcode.lib.php::barcode_encode Use genbarcode ".$genbarcode_loc." code=".$code." encoding=".$encoding);
135  $bars=barcode_encode_genbarcode($code, $encoding);
136  }
137  else
138  {
139  print "barcode_encode needs an external programm for encodings other then EAN/ISBN (code=".$code.", encoding=".$encoding.")<BR>\n";
140  print "<UL>\n";
141  print "<LI>download gnu-barcode from <A href=\"http://www.gnu.org/software/barcode/\">www.gnu.org/software/barcode/</A>\n";
142  print "<LI>compile and install them\n";
143  print "<LI>download genbarcode from <A href=\"http://www.ashberg.de/bar/\">www.ashberg.de/bar/</A>\n";
144  print "<LI>compile and install them\n";
145  print "<LI>specify path the genbarcode in barcode module setup\n";
146  print "</UL>\n";
147  print "<BR>\n";
148  return false;
149  }
150 
151  return $bars;
152 }
153 
154 
161 function barcode_gen_ean_sum($ean)
162 {
163  $even=true; $esum=0; $osum=0;
164  $ln=strlen($ean)-1;
165  for ($i=$ln; $i>=0; $i--)
166  {
167  if ($even) $esum+=$ean[$i]; else $osum+=$ean[$i];
168  $even=!$even;
169  }
170  return (10-((3*$esum+$osum)%10))%10;
171 }
172 
180 function barcode_encode_ean($ean, $encoding = "EAN-13")
181 {
182  $digits=array(3211,2221,2122,1411,1132,1231,1114,1312,1213,3112);
183  $mirror=array("000000","001011","001101","001110","010011","011001","011100","010101","010110","011010");
184  $guards=array("9a1a","1a1a1","a1a");
185 
186  $ean=trim($ean);
187  if (preg_match("/[^0-9]/i",$ean))
188  {
189  return array("error"=>"Invalid encoding/code. encoding=".$encoding." code=".$ean." (not a numeric)", "text"=>"Invalid encoding/code. encoding=".$encoding." code=".$ean." (not a numeric)");
190  }
191  $encoding=strtoupper($encoding);
192  if ($encoding=="ISBN")
193  {
194  if (!preg_match("/^978/", $ean)) $ean="978".$ean;
195  }
196  if (preg_match("/^978/", $ean)) $encoding="ISBN";
197  if (strlen($ean)<12 || strlen($ean)>13)
198  {
199  return array("error"=>"Invalid encoding/code. encoding=".$encoding." code=".$ean." (must have 12/13 numbers)", "text"=>"Invalid encoding/code. encoding=".$encoding." code=".$ean." (must have 12/13 numbers)");
200  }
201 
202  $ean=substr($ean,0,12);
203  $eansum=barcode_gen_ean_sum($ean);
204  $ean.=$eansum;
205  $line=$guards[0];
206  for ($i=1;$i<13;$i++)
207  {
208  $str=$digits[$ean[$i]];
209  if ($i<7 && $mirror[$ean[0]][$i-1]==1) $line.=strrev($str); else $line.=$str;
210  if ($i==6) $line.=$guards[1];
211  }
212  $line.=$guards[2];
213 
214  /* create text */
215  $pos=0;
216  $text="";
217  for ($a=0;$a<13;$a++)
218  {
219  if ($a>0) $text.=" ";
220  $text.="$pos:12:{$ean[$a]}";
221  if ($a==0) $pos+=12;
222  else if ($a==6) $pos+=12;
223  else $pos+=7;
224  }
225 
226  return array(
227  "error" => '',
228  "encoding" => $encoding,
229  "bars" => $line,
230  "text" => $text
231  );
232 }
233 
241 function barcode_encode_genbarcode($code,$encoding)
242 {
243  global $genbarcode_loc;
244 
245  // Clean parameters
246  if (preg_match("/^ean$/i", $encoding) && strlen($code)==13) $code=substr($code,0,12);
247  if (!$encoding) $encoding="ANY";
248  $encoding=preg_replace("/[\\\|]/", "_", $encoding);
249  $code=preg_replace("/[\\\|]/", "_", $code);
250 
251  $command=escapeshellarg($genbarcode_loc);
252  //$paramclear=" \"".str_replace("\"", "\\\"",$code)."\" \"".str_replace("\"", "\\\"",strtoupper($encoding))."\"";
253  $paramclear=" ".escapeshellarg($code)." ".escapeshellarg(strtoupper($encoding));
254 
255  $fullcommandclear=$command." ".$paramclear." 2>&1";
256  //print $fullcommandclear."<br>\n";exit;
257 
258  dol_syslog("Run command ".$fullcommandclear);
259  $fp=popen($fullcommandclear, "r");
260  if ($fp)
261  {
262  $bars=fgets($fp, 1024);
263  $text=fgets($fp, 1024);
264  $encoding=fgets($fp, 1024);
265  pclose($fp);
266  }
267  else
268  {
269  dol_syslog("barcode.lib.php::barcode_encode_genbarcode failed to run popen ".$fullcommandclear, LOG_ERR);
270  return false;
271  }
272  //var_dump($bars);
273  $ret=array(
274  "bars" => trim($bars),
275  "text" => trim($text),
276  "encoding" => trim($encoding),
277  "error" => ""
278  );
279  //var_dump($ret);
280  if (preg_match('/permission denied/i',$ret['bars']))
281  {
282  $ret['error']=$ret['bars']; $ret['bars']='';
283  return $ret;
284  }
285  if (!$ret['bars']) return false;
286  if (!$ret['text']) return false;
287  if (!$ret['encoding']) return false;
288  return $ret;
289 }
290 
302 function barcode_outimage($text, $bars, $scale = 1, $mode = "png", $total_y = 0, $space = '')
303 {
304  global $bar_color, $bg_color, $text_color;
305  global $font_loc, $filebarcode;
306 
307  //print "$text, $bars, $scale, $mode, $total_y, $space, $font_loc, $filebarcode<br>";
308  //var_dump($text);
309  //var_dump($bars);
310  //var_dump($font_loc);
311 
312  /* set defaults */
313  if ($scale<1) $scale=2;
314  $total_y=(int) $total_y;
315  if ($total_y<1) $total_y=(int) $scale * 60;
316  if (!$space)
317  $space=array('top'=>2*$scale,'bottom'=>2*$scale,'left'=>2*$scale,'right'=>2*$scale);
318 
319  /* count total width */
320  $xpos=0;
321  $width=true;
322  $ln=strlen($bars);
323  for ($i=0; $i<$ln; $i++)
324  {
325  $val=strtolower($bars[$i]);
326  if ($width)
327  {
328  $xpos+=$val*$scale;
329  $width=false;
330  continue;
331  }
332  if (preg_match("/[a-z]/", $val))
333  {
334  /* tall bar */
335  $val=ord($val)-ord('a')+1;
336  }
337  $xpos+=$val*$scale;
338  $width=true;
339  }
340 
341  /* allocate the image */
342  $total_x=( $xpos )+$space['right']+$space['right'];
343  $xpos=$space['left'];
344  if (! function_exists("imagecreate"))
345  {
346  print "You don't have the gd2 extension enabled<br>\n";
347  return "";
348  }
349  $im=imagecreate($total_x, $total_y);
350  /* create two images */
351  $col_bg=ImageColorAllocate($im,$bg_color[0],$bg_color[1],$bg_color[2]);
352  $col_bar=ImageColorAllocate($im,$bar_color[0],$bar_color[1],$bar_color[2]);
353  $col_text=ImageColorAllocate($im,$text_color[0],$text_color[1],$text_color[2]);
354  $height=round($total_y-($scale*10));
355  $height2=round($total_y-$space['bottom']);
356 
357  /* paint the bars */
358  $width=true;
359  $ln=strlen($bars);
360  for ($i=0; $i<$ln; $i++)
361  {
362  $val=strtolower($bars[$i]);
363  if ($width)
364  {
365  $xpos+=$val*$scale;
366  $width=false;
367  continue;
368  }
369  if (preg_match("/[a-z]/", $val))
370  {
371  /* tall bar */
372  $val=ord($val)-ord('a')+1;
373  $h=$height2;
374  } else $h=$height;
375  imagefilledrectangle($im, $xpos, $space['top'], $xpos+($val*$scale)-1, $h, $col_bar);
376  $xpos+=$val*$scale;
377  $width=true;
378  }
379 
380  $chars=explode(" ", $text);
381  reset($chars);
382  while (list($n, $v)=each($chars))
383  {
384  if (trim($v))
385  {
386  $inf=explode(":", $v);
387  $fontsize=$scale*($inf[1]/1.8);
388  $fontheight=$total_y-($fontsize/2.7)+2;
389  imagettftext($im, $fontsize, 0, $space['left']+($scale*$inf[0])+2, $fontheight, $col_text, $font_loc, $inf[2]);
390  }
391  }
392 
393  /* output the image */
394  $mode=strtolower($mode);
395  if ($mode=='jpg' || $mode=='jpeg')
396  {
397  header("Content-Type: image/jpeg; name=\"barcode.jpg\"");
398  imagejpeg($im);
399  }
400  else if ($mode=='gif')
401  {
402  header("Content-Type: image/gif; name=\"barcode.gif\"");
403  imagegif($im);
404  }
405  else if (! empty($filebarcode)) // To wxrite into afile onto disk
406  {
407  imagepng($im,$filebarcode);
408  }
409  else
410  {
411  header("Content-Type: image/png; name=\"barcode.png\"");
412  imagepng($im);
413  }
414 }
415 
barcode_encode($code, $encoding)
Encodes $code with $encoding using genbarcode OR built-in encoder if you don't have genbarcode only E...
barcode_gen_ean_sum($ean)
Calculate EAN sum.
barcode_print($code, $encoding="ANY", $scale=2, $mode="png")
Print barcode.
Definition: barcode.lib.php:68
barcode_encode_ean($ean, $encoding="EAN-13")
Encode EAN.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
print
Draft customers invoices.
Definition: index.php:91
barcode_encode_genbarcode($code, $encoding)
Encode result of genbarcode command.
barcode_outimage($text, $bars, $scale=1, $mode="png", $total_y=0, $space= '')
Output image onto standard output, or onto disk if global filebarcode is defined. ...