dolibarr  13.0.2
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 <https://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  } elseif (file_exists($genbarcode_loc)) // For example C39
131  {
132  /* use genbarcode */
133  dol_syslog("barcode.lib.php::barcode_encode Use genbarcode ".$genbarcode_loc." code=".$code." encoding=".$encoding);
134  $bars = barcode_encode_genbarcode($code, $encoding);
135  } else {
136  print "barcode_encode needs an external programm for encodings other then EAN/ISBN (code=".$code.", encoding=".$encoding.")<BR>\n";
137  print "<UL>\n";
138  print "<LI>download gnu-barcode from <A href=\"https://www.gnu.org/software/barcode/\">www.gnu.org/software/barcode/</A>\n";
139  print "<LI>compile and install them\n";
140  print "<LI>download genbarcode from <A href=\"http://www.ashberg.de/bar/\">www.ashberg.de/bar/</A>\n";
141  print "<LI>compile and install them\n";
142  print "<LI>specify path the genbarcode in barcode module setup\n";
143  print "</UL>\n";
144  print "<BR>\n";
145  return false;
146  }
147 
148  return $bars;
149 }
150 
151 
158 function barcode_gen_ean_sum($ean)
159 {
160  $even = true; $esum = 0; $osum = 0;
161  $ln = strlen($ean) - 1;
162  for ($i = $ln; $i >= 0; $i--)
163  {
164  if ($even) $esum += $ean[$i]; else $osum += $ean[$i];
165  $even = !$even;
166  }
167  return (10 - ((3 * $esum + $osum) % 10)) % 10;
168 }
169 
177 function barcode_encode_ean($ean, $encoding = "EAN-13")
178 {
179  $digits = array(3211, 2221, 2122, 1411, 1132, 1231, 1114, 1312, 1213, 3112);
180  $mirror = array("000000", "001011", "001101", "001110", "010011", "011001", "011100", "010101", "010110", "011010");
181  $guards = array("9a1a", "1a1a1", "a1a");
182 
183  $ean = trim($ean);
184  if (preg_match("/[^0-9]/i", $ean))
185  {
186  return array("error"=>"Invalid encoding/code. encoding=".$encoding." code=".$ean." (not a numeric)", "text"=>"Invalid encoding/code. encoding=".$encoding." code=".$ean." (not a numeric)");
187  }
188  $encoding = strtoupper($encoding);
189  if ($encoding == "ISBN")
190  {
191  if (!preg_match("/^978/", $ean)) $ean = "978".$ean;
192  }
193  if (preg_match("/^978/", $ean)) $encoding = "ISBN";
194  if (strlen($ean) < 12 || strlen($ean) > 13)
195  {
196  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)");
197  }
198 
199  $ean = substr($ean, 0, 12);
200  $eansum = barcode_gen_ean_sum($ean);
201  $ean .= $eansum;
202  $line = $guards[0];
203  for ($i = 1; $i < 13; $i++)
204  {
205  $str = $digits[$ean[$i]];
206  if ($i < 7 && $mirror[$ean[0]][$i - 1] == 1) $line .= strrev($str); else $line .= $str;
207  if ($i == 6) $line .= $guards[1];
208  }
209  $line .= $guards[2];
210 
211  /* create text */
212  $pos = 0;
213  $text = "";
214  for ($a = 0; $a < 13; $a++)
215  {
216  if ($a > 0) $text .= " ";
217  $text .= "$pos:12:{$ean[$a]}";
218  if ($a == 0) $pos += 12;
219  elseif ($a == 6) $pos += 12;
220  else $pos += 7;
221  }
222 
223  return array(
224  "error" => '',
225  "encoding" => $encoding,
226  "bars" => $line,
227  "text" => $text
228  );
229 }
230 
238 function barcode_encode_genbarcode($code, $encoding)
239 {
240  global $genbarcode_loc;
241 
242  // Clean parameters
243  if (preg_match("/^ean$/i", $encoding) && strlen($code) == 13) $code = substr($code, 0, 12);
244  if (!$encoding) $encoding = "ANY";
245  $encoding = preg_replace("/[\\\|]/", "_", $encoding);
246  $code = preg_replace("/[\\\|]/", "_", $code);
247 
248  $command = escapeshellarg($genbarcode_loc);
249  //$paramclear=" \"".str_replace("\"", "\\\"",$code)."\" \"".str_replace("\"", "\\\"",strtoupper($encoding))."\"";
250  $paramclear = " ".escapeshellarg($code)." ".escapeshellarg(strtoupper($encoding));
251 
252  $fullcommandclear = $command." ".$paramclear." 2>&1";
253  //print $fullcommandclear."<br>\n";exit;
254 
255  dol_syslog("Run command ".$fullcommandclear);
256  $fp = popen($fullcommandclear, "r");
257  if ($fp)
258  {
259  $bars = fgets($fp, 1024);
260  $text = fgets($fp, 1024);
261  $encoding = fgets($fp, 1024);
262  pclose($fp);
263  } else {
264  dol_syslog("barcode.lib.php::barcode_encode_genbarcode failed to run popen ".$fullcommandclear, LOG_ERR);
265  return false;
266  }
267  //var_dump($bars);
268  $ret = array(
269  "bars" => trim($bars),
270  "text" => trim($text),
271  "encoding" => trim($encoding),
272  "error" => ""
273  );
274  //var_dump($ret);
275  if (preg_match('/permission denied/i', $ret['bars']))
276  {
277  $ret['error'] = $ret['bars']; $ret['bars'] = '';
278  return $ret;
279  }
280  if (!$ret['bars']) return false;
281  if (!$ret['text']) return false;
282  if (!$ret['encoding']) return false;
283  return $ret;
284 }
285 
297 function barcode_outimage($text, $bars, $scale = 1, $mode = "png", $total_y = 0, $space = '')
298 {
299  global $bar_color, $bg_color, $text_color;
300  global $font_loc, $filebarcode;
301 
302  //print "$text, $bars, $scale, $mode, $total_y, $space, $font_loc, $filebarcode<br>";
303  //var_dump($text);
304  //var_dump($bars);
305  //var_dump($font_loc);
306 
307  /* set defaults */
308  if ($scale < 1) $scale = 2;
309  $total_y = (int) $total_y;
310  if ($total_y < 1) $total_y = (int) $scale * 60;
311  if (!$space)
312  $space = array('top'=>2 * $scale, 'bottom'=>2 * $scale, 'left'=>2 * $scale, 'right'=>2 * $scale);
313 
314  /* count total width */
315  $xpos = 0;
316  $width = true;
317  $ln = strlen($bars);
318  for ($i = 0; $i < $ln; $i++)
319  {
320  $val = strtolower($bars[$i]);
321  if ($width)
322  {
323  $xpos += $val * $scale;
324  $width = false;
325  continue;
326  }
327  if (preg_match("/[a-z]/", $val))
328  {
329  /* tall bar */
330  $val = ord($val) - ord('a') + 1;
331  }
332  $xpos += $val * $scale;
333  $width = true;
334  }
335 
336  /* allocate the image */
337  $total_x = ($xpos) + $space['right'] + $space['right'];
338  $xpos = $space['left'];
339  if (!function_exists("imagecreate"))
340  {
341  print "You don't have the gd2 extension enabled<br>\n";
342  return "";
343  }
344  $im = imagecreate($total_x, $total_y);
345  /* create two images */
346  $col_bg = ImageColorAllocate($im, $bg_color[0], $bg_color[1], $bg_color[2]);
347  $col_bar = ImageColorAllocate($im, $bar_color[0], $bar_color[1], $bar_color[2]);
348  $col_text = ImageColorAllocate($im, $text_color[0], $text_color[1], $text_color[2]);
349  $height = round($total_y - ($scale * 10));
350  $height2 = round($total_y - $space['bottom']);
351 
352  /* paint the bars */
353  $width = true;
354  $ln = strlen($bars);
355  for ($i = 0; $i < $ln; $i++)
356  {
357  $val = strtolower($bars[$i]);
358  if ($width)
359  {
360  $xpos += $val * $scale;
361  $width = false;
362  continue;
363  }
364  if (preg_match("/[a-z]/", $val))
365  {
366  /* tall bar */
367  $val = ord($val) - ord('a') + 1;
368  $h = $height2;
369  } else $h = $height;
370  imagefilledrectangle($im, $xpos, $space['top'], $xpos + ($val * $scale) - 1, $h, $col_bar);
371  $xpos += $val * $scale;
372  $width = true;
373  }
374 
375  $chars = explode(" ", $text);
376  foreach ($chars as $v) {
377  if (trim($v)) {
378  $inf = explode(":", $v);
379  $fontsize = $scale * ($inf[1] / 1.8);
380  $fontheight = $total_y - ($fontsize / 2.7) + 2;
381  imagettftext($im, $fontsize, 0, $space['left'] + ($scale * $inf[0]) + 2, $fontheight, $col_text, $font_loc, $inf[2]);
382  }
383  }
384 
385  /* output the image */
386  $mode = strtolower($mode);
387  if ($mode == 'jpg' || $mode == 'jpeg') {
388  header("Content-Type: image/jpeg; name=\"barcode.jpg\"");
389  imagejpeg($im);
390  } elseif ($mode == 'gif') {
391  header("Content-Type: image/gif; name=\"barcode.gif\"");
392  imagegif($im);
393  } elseif (!empty($filebarcode)) {
394  // To wxrite into afile onto disk
395  imagepng($im, $filebarcode);
396  } else {
397  header("Content-Type: image/png; name=\"barcode.png\"");
398  imagepng($im);
399  }
400 }
barcode_encode($code, $encoding)
Encodes $code with $encoding using genbarcode OR built-in encoder if you don&#39;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= '', $logcontext=null)
Write log message into outputs.
print $_SERVER["PHP_SELF"]
Edit parameters.
print
Draft customers invoices.
Definition: index.php:89
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. ...