1<?php 2 3namespace jucksearm\barcode\lib; 4 5use jucksearm\barcode\lib\Barcode1D; 6 7class BarcodeFactory 8{ 9 private $_attributes; 10 private $_scalePx = 1; 11 private $_heightPx = 1; 12 13 public function __construct() 14 { 15 $this->_attributes = [ 16 'code' => null, 17 'type' => null, 18 'file' => null, 19 'scale' => 1, 20 'height' => 30, 21 'rotate' => 0, 22 'color' => '000', 23 ]; 24 } 25 26 public function __set($name, $value) 27 { 28 $setter = 'set' . $name; 29 if (method_exists($this, $setter)) { 30 // set property 31 $this->$setter($value); 32 33 return; 34 } 35 } 36 37 public function __get($name) 38 { 39 $getter = 'get' . $name; 40 if (method_exists($this, $getter)) { 41 // read property 42 return $this->$getter(); 43 } 44 } 45 46 public function setAttribute($name, $value) 47 { 48 if ($value === null) return; 49 50 $this->_attributes[$name] = $value; 51 } 52 53 public function getAttribute($name) 54 { 55 return $this->_attributes[$name]; 56 } 57 58 public function setAttributes($attrs = []) 59 { 60 array_merge($this->_attributes, $attrs); 61 } 62 63 public function getAttributes() 64 { 65 return $this->_attributes; 66 } 67 68 public function setCode($value) 69 { 70 $this->setAttribute('code', $value); 71 return $this; 72 } 73 74 public function getCode() 75 { 76 return $this->getAttribute('code'); 77 } 78 79 public function setType($value) 80 { 81 $this->setAttribute('type', $value); 82 return $this; 83 } 84 85 public function getType() 86 { 87 return $this->getAttribute('type'); 88 } 89 90 public function setFile($value) 91 { 92 $this->setAttribute('file', $value); 93 return $this; 94 } 95 96 public function getFile() 97 { 98 return $this->getAttribute('file'); 99 } 100 101 public function setScale($value) 102 { 103 $this->setAttribute('scale', $value); 104 return $this; 105 } 106 107 public function getScale() 108 { 109 return $this->getAttribute('scale') * $this->_scalePx; 110 } 111 112 public function setHeight($value) 113 { 114 $this->setAttribute('height', $value); 115 return $this; 116 } 117 118 public function getHeight() 119 { 120 return $this->getAttribute('height') * $this->_heightPx; 121 } 122 123 public function setRotate($value) 124 { 125 $value = abs($value); 126 if ($value != 0 && $value%90 != 0) return $this; 127 128 $this->setAttribute('rotate', $value); 129 return $this; 130 } 131 132 public function getRotate() 133 { 134 return $this->getAttribute('rotate'); 135 } 136 137 public function setColor($value) 138 { 139 $this->setAttribute('color', $value); 140 return $this; 141 } 142 143 public function getColor() 144 { 145 return $this->getAttribute('color'); 146 } 147 148 public function getBarcode() 149 { 150 return new Barcode1D($this->code, $this->type); 151 } 152 153 public function getHexColor() 154 { 155 $color = $this->color; 156 157 return '#'.$color; 158 } 159 160 public function getRgbColor() 161 { 162 $color = $this->color; 163 164 if (strlen($color) > 3) { 165 $r = hexdec(substr($color, 0, 2)); 166 $g = hexdec(substr($color, 2, 2)); 167 $b = hexdec(substr($color, 4, 2)); 168 } else { 169 $r = hexdec(substr($color, 0, 1).substr($color, 0, 1)); 170 $g = hexdec(substr($color, 1, 1).substr($color, 1, 1)); 171 $b = hexdec(substr($color, 2, 1).substr($color, 2, 1)); 172 } 173 174 return [$r, $g, $b]; 175 } 176 177 public function getBarcodeHtmlData() 178 { 179 $bcd = $this->barcode->getBarcodeArray(); 180 $rotate = $this->rotate; 181 $color = $this->hexColor; 182 183 if ($rotate == 0 || $rotate%180 == 0) { 184 $w = $this->scale; 185 $h = $this->height; 186 187 $barcodeData = '<div style="font-size:0;position:relative;width:'.($bcd['maxw'] * $w).'px;height:'.($h).'px;">'."\n"; 188 // print bars 189 $x = 0; 190 foreach ($bcd['bcode'] as $k => $v) { 191 $bw = round(($v['w'] * $w), 3); 192 $bh = round(($v['h'] * $h / $bcd['maxh']), 3); 193 if ($v['t']) { 194 $y = round(($v['p'] * $h / $bcd['maxh']), 3); 195 // draw a vertical bar 196 $barcodeData .= '<div style="background-color:'.$color.';width:'.$bw.'px;height:'.$bh.'px;position:absolute;left:'.$x.'px;top:'.$y.'px;"> </div>'."\n"; 197 } 198 $x += $bw; 199 } 200 $barcodeData .= '</div>'."\n"; 201 } else { 202 $w = $this->height; 203 $h = $this->scale; 204 205 $barcodeData = '<div style="font-size:0;position:relative;width:'.($w).'px;height:'.($bcd['maxw'] * $h).'px;">'."\n"; 206 // print bars 207 $y = 0; 208 foreach ($bcd['bcode'] as $k => $v) { 209 $bw = round(($v['h'] * $w / $bcd['maxh']), 3); 210 $bh = round(($v['w'] * $h), 3); 211 if ($v['t']) { 212 $x = round(($v['p'] * $h / $bcd['maxh']), 3); 213 // draw a vertical bar 214 $barcodeData .= '<div style="background-color:'.$color.';width:'.$bw.'px;height:'.$bh.'px;position:absolute;left:'.$x.'px;top:'.$y.'px;"> </div>'."\n"; 215 } 216 $y += $bh; 217 } 218 $barcodeData .= '</div>'."\n"; 219 } 220 221 return $barcodeData; 222 } 223 224 public function getBarcodePngData() 225 { 226 $bcd = $this->barcode->getBarcodeArray(); 227 $rotate = $this->rotate; 228 $color = $this->rgbColor; 229 230 if ($rotate == 0 || $rotate%180 == 0) { 231 $w = $this->scale; 232 $h = $this->height; 233 234 if (function_exists('imagecreate')) { 235 $png = imagecreate(($bcd['maxw'] * $w), $h); 236 $bgcol = imagecolorallocate($png, 255, 255, 255); 237 // imagecolortransparent($png, $bgcol); 238 $fgcol = imagecolorallocate($png, $color[0], $color[1], $color[2]); 239 } else { 240 return false; 241 } 242 // print bars 243 $x = 0; 244 foreach ($bcd['bcode'] as $k => $v) { 245 $bw = round(($v['w'] * $w), 3); 246 $bh = round(($v['h'] * $h / $bcd['maxh']), 3); 247 if ($v['t']) { 248 $y = round(($v['p'] * $h / $bcd['maxh']), 3); 249 // draw a vertical bar 250 if ($imagick) { 251 $bar->rectangle($x, $y, ($x + $bw - 1), ($y + $bh - 1)); 252 } else { 253 imagefilledrectangle($png, $x, $y, ($x + $bw - 1), ($y + $bh - 1), $fgcol); 254 } 255 } 256 $x += $bw; 257 } 258 } else { 259 $w = $this->height; 260 $h = $this->scale; 261 262 if (function_exists('imagecreate')) { 263 $png = imagecreate($w, ($bcd['maxw'] * $h)); 264 $bgcol = imagecolorallocate($png, 255, 255, 255); 265 // imagecolortransparent($png, $bgcol); 266 $fgcol = imagecolorallocate($png, $color[0], $color[1], $color[2]); 267 } else { 268 return false; 269 } 270 // print bars 271 $y = 0; 272 foreach ($bcd['bcode'] as $k => $v) { 273 $bw = round(($v['h'] * $w / $bcd['maxh']), 3); 274 $bh = round(($v['w'] * $h), 3); 275 if ($v['t']) { 276 $x = round(($v['p'] * $h / $bcd['maxh']), 3); 277 imagefilledrectangle($png, $x, $y, ($x + $bw - 1), ($y + $bh - 1), $fgcol); 278 } 279 $y += $bh; 280 } 281 } 282 283 if ($this->file === null) { 284 ob_start(); 285 imagepng($png); 286 $barcodeData = ob_get_clean(); 287 } else { 288 preg_match("/\.png$/", $this->file, $output); 289 if (count($output) == 0) 290 throw new \Exception('Incorrect file extension format.'); 291 292 $filePath = explode(DIRECTORY_SEPARATOR, $this->file); 293 if (count($filePath) == 1 ) { 294 $savePath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.$this->file; 295 } else { 296 $savePath = $this->file; 297 } 298 299 if (!@imagepng($png, $savePath)) 300 throw new \Exception('Not found save path.'); 301 302 $barcodeData = file_get_contents($savePath); 303 } 304 305 imagedestroy($png); 306 307 return $barcodeData; 308 } 309 310 public function getBarcodeSvgData() 311 { 312 $bcd = $this->barcode->getBarcodeArray(); 313 $rotate = $this->rotate; 314 $color = $this->hexColor; 315 316 if ($rotate == 0 || $rotate%180 == 0) { 317 $w = $this->scale; 318 $h = $this->height; 319 320 $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); 321 $barcodeData = '<'.'?'.'xml version="1.0" standalone="no"'.'?'.'>'."\n"; 322 $barcodeData .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n"; 323 $barcodeData .= '<svg width="'.round(($bcd['maxw'] * $w), 3).'" height="'.$h.'" version="1.1" xmlns="http://www.w3.org/2000/svg">'."\n"; 324 $barcodeData .= "\t".'<desc>'.strtr($bcd['code'], $repstr).'</desc>'."\n"; 325 $barcodeData .= "\t".'<g id="bars" fill="'.$color.'" stroke="none">'."\n"; 326 // print bars 327 $x = 0; 328 foreach ($bcd['bcode'] as $k => $v) { 329 $bw = round(($v['w'] * $w), 3); 330 $bh = round(($v['h'] * $h / $bcd['maxh']), 3); 331 if ($v['t']) { 332 $y = round(($v['p'] * $h / $bcd['maxh']), 3); 333 // draw a vertical bar 334 $barcodeData .= "\t\t".'<rect x="'.$x.'" y="'.$y.'" width="'.$bw.'" height="'.$bh.'" />'."\n"; 335 } 336 $x += $bw; 337 } 338 $barcodeData .= "\t".'</g>'."\n"; 339 $barcodeData .= '</svg>'."\n"; 340 } else { 341 $w = $this->height; 342 $h = $this->scale; 343 344 $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); 345 $barcodeData = '<'.'?'.'xml version="1.0" standalone="no"'.'?'.'>'."\n"; 346 $barcodeData .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n"; 347 $barcodeData .= '<svg width="'.$w.'" height="'.round(($bcd['maxw'] * $h), 3).'" version="1.1" xmlns="http://www.w3.org/2000/svg">'."\n"; 348 $barcodeData .= "\t".'<desc>'.strtr($bcd['code'], $repstr).'</desc>'."\n"; 349 $barcodeData .= "\t".'<g id="bars" fill="'.$color.'" stroke="none">'."\n"; 350 // print bars 351 $y = 0; 352 foreach ($bcd['bcode'] as $k => $v) { 353 $bw = round(($v['h'] * $w / $bcd['maxh']), 3); 354 $bh = round(($v['w'] * $h), 3); 355 if ($v['t']) { 356 $x = round(($v['p'] * $h / $bcd['maxh']), 3); 357 // draw a vertical bar 358 $barcodeData .= "\t\t".'<rect x="'.$x.'" y="'.$y.'" width="'.$bw.'" height="'.$bh.'" />'."\n"; 359 } 360 $y += $bh; 361 } 362 $barcodeData .= "\t".'</g>'."\n"; 363 $barcodeData .= '</svg>'."\n"; 364 } 365 366 if ($this->file != null) { 367 preg_match("/\.svg$/", $this->file, $output); 368 if (count($output) == 0) 369 throw new \Exception('Incorrect file extension format.'); 370 371 $filePath = explode(DIRECTORY_SEPARATOR, $this->file); 372 if (count($filePath) == 1 ) { 373 $savePath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.$this->file; 374 } else { 375 $savePath = $this->file; 376 } 377 378 if (!@file_put_contents($savePath, $barcodeData)) 379 throw new \Exception('Not found save path.'); 380 } 381 382 return $barcodeData; 383 } 384 385 public function renderHTML() 386 { 387 $barcodeData = $this->getBarcodeHtmlData(); 388 389 header('Content-Type: text/html'); 390 header('Content-Length: '.strlen($barcodeData)); 391 header('Cache-Control: no-cache'); 392 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 393 394 echo $barcodeData; 395 } 396 397 public function renderPNG() 398 { 399 $barcodeData = $this->getBarcodePngData(); 400 401 header('Content-Type: image/png'); 402 header('Content-Length: '.strlen($barcodeData)); 403 header('Cache-Control: no-cache'); 404 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 405 406 echo $barcodeData; 407 } 408 409 public function renderSVG() 410 { 411 $barcodeData = $this->getBarcodeSvgData(); 412 413 header('Content-Type: image/svg+xml'); 414 header('Content-Length: '.strlen($barcodeData)); 415 header('Cache-Control: no-cache'); 416 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 417 418 echo $barcodeData; 419 } 420}