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        // attribute: logo
91        if ($this->factory instanceof QRcodeFactory) $this->factory->setEmblem($this->attributes->logo);
92    }
93
94    public function getStyle() {
95        $styles = array();
96
97        // attribute: background-color
98        if ($this->attributes->background_color) $styles[] = sprintf('background-color: #%s', $this->attributes->background_color);
99
100        // attribute: size
101        if ($this->attributes->size) {
102            if ($this->factory instanceof QRcodeFactory || $this->factory instanceof DatamatrixFactory) {
103                $styles[] = sprintf('width: %dpx', $this->attributes->size);
104                $styles[] = sprintf('height: %dpx', $this->attributes->size);
105            }
106            elseif ($this->factory instanceof BarcodeFactory) {
107                $styles[] = sprintf('height: %dpx', $this->attributes->size);
108            }
109        }
110
111        // attribute: padding
112        $styles[] = sprintf('padding: %dpx', $this->attributes->padding);
113
114        // return
115        return implode('; ', $styles);
116    }
117
118    /**
119     * @throws BarcodesException
120     */
121    public function getImgSrc() {
122        if ($this->attributes->img_type == 'svg') {
123            if ($this->factory instanceof QRcodeFactory) {
124                $svg = $this->factory->getQRcodeSvgData();
125            } elseif ($this->factory instanceof DatamatrixFactory) {
126                $svg = $this->factory->getDatamatrixSvgData();
127            } elseif ($this->factory instanceof BarcodeFactory) {
128                $svg = $this->factory->getBarcodeSvgData();
129            } else {
130                throw new BarcodesException('BUG: Missing factory handler! Please open ticket!');
131            }
132            return 'data:image/svg+xml;base64,' . base64_encode($svg);
133        } elseif ($this->attributes->img_type == 'png') {
134            if ($this->factory instanceof QRcodeFactory) {
135                $png = $this->factory->getQRcodePngData();
136            } elseif ($this->factory instanceof DatamatrixFactory) {
137                $png = $this->factory->getDatamatrixPngData();
138            } elseif ($this->factory instanceof BarcodeFactory) {
139                $png = $this->factory->getBarcodePngData();
140            } else {
141                throw new BarcodesException('BUG: Missing factory handler! Please open ticket!');
142            }
143            return 'data:image/png;base64,' . base64_encode($png);
144        } else {
145            throw new BarcodesException('Unsupported img-type "' . $this->attributes->img_type . '"');
146        }
147    }
148
149    public function getHtml() {
150        return '<img style="' . $this->getStyle() . '" src="' . $this->getImgSrc() . '" />';
151    }
152}
153