1<?php
2
3/**
4 * DokuWiki Barcodes Plugin
5 * Copyright (C) 2023 Matthias Lohr <mail@mlohr.com>
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
21namespace DokuWiki\Barcodes;
22
23use jucksearm\barcode\Barcode;
24use jucksearm\barcode\Datamatrix;
25use jucksearm\barcode\lib\BarcodeFactory;
26use jucksearm\barcode\lib\DatamatrixFactory;
27use jucksearm\barcode\lib\QRcodeFactory;
28use jucksearm\barcode\QRcode;
29
30class BarcodesWrapper {
31
32    private $factory;
33    private $attributes;
34
35    const JUCKESARM_BARCODES = array(
36        "C39", "C39+", "C39E", "C39E+", "C93", "S25", "S25+", "I25", "I25+", "C128", "C128A", "C128B", "C128C", "EAN2",
37        "EAN5", "EAN8", "EAN13", "UPCA", "UPCE", "MSI", "MSI+", "POSTNET", "PLANET", "RMS4CC", "KIX", "IMB", "CODABAR",
38        "CODE11", "PHARMA", "PHARMA2T"
39    );
40
41    public function __construct($attributes)
42    {
43        $this->attributes = $attributes;
44        $this->applyAttributes();
45    }
46
47    /**
48     * @throws BarcodesException
49     */
50    private function applyAttributes() {
51        // attribute: type
52        if (!$this->attributes->type) {
53            throw new BarcodesException('type cannot be empty');
54        }
55        elseif ($this->attributes->type == "QRCODE") {
56            $this->factory = QRcode::factory();
57            $this->factory->setMargin(0);
58        }
59        elseif ($this->attributes->type == "DATAMATRIX") {
60            $this->factory = Datamatrix::factory();
61            $this->factory->setMargin(0);
62        }
63        elseif (in_array($this->attributes->type, self::JUCKESARM_BARCODES)) {
64            $this->factory = Barcode::factory();
65            $this->factory->setType($this->attributes->type);
66        }
67        else {
68            throw new BarcodesException('unsupported type "' . $this->attributes->type . '"');
69        }
70
71        // attribute: value
72        $this->factory->setCode($this->attributes->value);
73
74        // attribute: color
75        $this->factory->setColor($this->attributes->color);
76
77        // attribute: size
78        if ($this->attributes->size) {
79            if ($this->factory instanceof QRcodeFactory || $this->factory instanceof DatamatrixFactory) {
80                $this->factory->setSize($this->attributes->size);
81            }
82            elseif ($this->factory instanceof BarcodeFactory) {
83                $this->factory->setHeight($this->attributes->size);
84            }
85        }
86
87        // attribute: scale
88        if ($this->factory instanceof BarcodeFactory) $this->factory->setScale($this->attributes->scale);
89    }
90
91    public function getStyle() {
92        $styles = array();
93
94        // attribute: background-color
95        if ($this->attributes->background_color) $styles[] = sprintf('background-color: #%s', $this->attributes->background_color);
96
97        // attribute: size
98        if ($this->attributes->size) {
99            if ($this->factory instanceof QRcodeFactory || $this->factory instanceof DatamatrixFactory) {
100                $styles[] = sprintf('width: %dpx', $this->attributes->size);
101                $styles[] = sprintf('height: %dpx', $this->attributes->size);
102            }
103            elseif ($this->factory instanceof BarcodeFactory) {
104                $styles[] = sprintf('height: %dpx', $this->attributes->size);
105            }
106        }
107
108        // attribute: padding
109        $styles[] = sprintf('padding: %dpx', $this->attributes->padding);
110
111        // return
112        return implode('; ', $styles);
113    }
114
115    /**
116     * @throws BarcodesException
117     */
118    public function getImgSrc() {
119        if ($this->attributes->img_type == 'svg') {
120            if ($this->factory instanceof QRcodeFactory) {
121                $svg = $this->factory->getQRcodeSvgData();
122            } elseif ($this->factory instanceof DatamatrixFactory) {
123                $svg = $this->factory->getDatamatrixSvgData();
124            } elseif ($this->factory instanceof BarcodeFactory) {
125                $svg = $this->factory->getBarcodeSvgData();
126            } else {
127                throw new BarcodesException('BUG: Missing factory handler! Please open ticket!');
128            }
129            return 'data:image/svg+xml;base64,' . base64_encode($svg);
130        } elseif ($this->attributes->img_type == 'png') {
131            if ($this->factory instanceof QRcodeFactory) {
132                $png = $this->factory->getQRcodePngData();
133            } elseif ($this->factory instanceof DatamatrixFactory) {
134                $png = $this->factory->getDatamatrixPngData();
135            } elseif ($this->factory instanceof BarcodeFactory) {
136                $png = $this->factory->getBarcodePngData();
137            } else {
138                throw new BarcodesException('BUG: Missing factory handler! Please open ticket!');
139            }
140            return 'data:image/png;base64,' . base64_encode($png);
141        } else {
142            throw new BarcodesException('Unsupported img-type "' . $this->attributes->img_type . '"');
143        }
144    }
145
146    public function getHtml() {
147        return '<img style="' . $this->getStyle() . '" src="' . $this->getImgSrc() . '" />';
148    }
149}
150