diff --git a/Dockerfile b/Dockerfile
index 7e801d9..5668259 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,15 +1,82 @@
-FROM php:latest
+FROM php:8.3
-RUN apt-get update && \
- apt-get install -y --no-install-recommends less nano tini curl bash tar git zip unzip && \
- #echo "**** # To install networking tools for testing purpose ****" && \
- apt-get install -y --no-install-recommends iputils-ping dnsutils net-tools procps && \
- #echo "**** cleanup ****" && \
- apt-get autoremove -y && \
- apt-get clean -y
+RUN if [ "$(grep '^VERSION_ID=' /etc/os-release | cut -d '=' -f 2 | tr -d '"')" -eq "9" ]; then \
+ sed -i -e 's/deb.debian.org/archive.debian.org/g' \
+ -e 's/security.debian.org/archive.debian.org/g' \
+ -e '/stretch-updates/d' /etc/apt/sources.list; \
+ fi
-RUN apt-get update
-RUN apt-get install -y --no-install-recommends libzip-dev libjpeg62-turbo-dev libpng-dev libfreetype6-dev
+# Download script to install PHP extensions and dependencies
+ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
+
+RUN chmod +x /usr/local/bin/install-php-extensions
+
+RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y \
+ curl \
+ dnsutils \
+ git \
+ iputils-ping \
+ less \
+ libzip-dev \
+ libjpeg62-turbo-dev \
+ libpng-dev \
+ libfreetype6-dev \
+ nano \
+ net-tools \
+ procps \
+ tar \
+ tini \
+ zip unzip \
+# iconv, mbstring and pdo_sqlite are omitted as they are already installed
+ && PHP_EXTENSIONS=" \
+ amqp \
+ bcmath \
+ bz2 \
+ calendar \
+ event \
+ exif \
+ gd \
+ gettext \
+ intl \
+ ldap \
+ memcached \
+ mysqli \
+ opcache \
+ pdo_mysql \
+ pdo_pgsql \
+ pgsql \
+ redis \
+ soap \
+ sockets \
+ xsl \
+ zip \
+ " \
+ && case "$PHP_VERSION" in \
+ 5.6.*) PHP_EXTENSIONS="$PHP_EXTENSIONS mcrypt mysql";; \
+ 7.0.*|7.1.*) PHP_EXTENSIONS="$PHP_EXTENSIONS mcrypt";; \
+ esac \
+ # Install Imagick from master on PHP >= 8.3, because imagick 3.7.0 broke on latest PHP releases and Imagick maintainers don't care to tag a newer release
+ && if [ $(php -r 'echo PHP_VERSION_ID;') -lt 80300 ]; then \
+ PHP_EXTENSIONS="$PHP_EXTENSIONS imagick"; \
+ else PHP_EXTENSIONS="$PHP_EXTENSIONS https://api.github.com/repos/Imagick/imagick/tarball/28f27044e435a2b203e32675e942eb8de620ee58"; \
+ fi \
+ && install-php-extensions $PHP_EXTENSIONS \
+ && if command -v a2enmod; then a2enmod rewrite; fi
+
+# Install Composer.
+ENV PATH=$PATH:/root/composer/vendor/bin \
+ COMPOSER_ALLOW_SUPERUSER=1 \
+ COMPOSER_HOME=/root/composer
+RUN cd /opt \
+ # Download installer and check for its integrity.
+ && curl -sSL https://getcomposer.org/installer > composer-setup.php \
+ && curl -sSL https://composer.github.io/installer.sha384sum > composer-setup.sha384sum \
+ && sha384sum --check composer-setup.sha384sum \
+ # Install Composer 2.
+ && php composer-setup.php --install-dir=/usr/local/bin --filename=composer --2 \
+ # Remove installer files.
+ && rm /opt/composer-setup.php /opt/composer-setup.sha384sum
RUN docker-php-source extract
RUN docker-php-ext-install pdo_mysql zip exif pcntl gd
@@ -17,7 +84,17 @@ RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
RUN docker-php-ext-install gettext && docker-php-ext-enable gettext
RUN docker-php-ext-install sockets && docker-php-ext-enable sockets
+RUN mkdir -p /opt && chmod 777 /opt
+WORKDIR /opt
+RUN git clone https://github.com/chillerlan/php-qrcode.git \
+ && chmod -R 777 ./php-qrcode
+RUN cp ./php-qrcode/composer.json /var/www/html/composer.json
+RUN mkdir -p /var/www/html/test && chmod 777 /var/www/html/test
+RUN cp ./php-qrcode/examples/image.php /var/www/html/test/image.php
+RUN cp -R ./php-qrcode/src /var/www/html/
+
WORKDIR /var/www/html
+RUN composer update
COPY ./src ./
RUN chmod 755 *;
EXPOSE 80
diff --git a/src/forms/qrcode_options.php b/src/forms/qrcode_options.php
index d918862..b7f3b34 100644
--- a/src/forms/qrcode_options.php
+++ b/src/forms/qrcode_options.php
@@ -45,6 +45,7 @@
+
@@ -75,6 +76,7 @@
+
@@ -107,4 +109,4 @@
"/>
-
\ No newline at end of file
+
diff --git a/src/forms/table_static.php b/src/forms/table_static.php
index 4fa8e18..23a72ad 100644
--- a/src/forms/table_static.php
+++ b/src/forms/table_static.php
@@ -58,7 +58,7 @@
|
|
- |
+ |
'; ?>
|
diff --git a/src/lib/Qrcode/Qrcode.php b/src/lib/Qrcode/Qrcode.php
index 8686d09..0043258 100644
--- a/src/lib/Qrcode/Qrcode.php
+++ b/src/lib/Qrcode/Qrcode.php
@@ -1,5 +1,19 @@
setOptions($input_data);
- if(!file_exists(SAVED_QRCODE_DIRECTORY.$data_to_db['filename'].'.'.$data_to_db['format'])){
- $url =
- 'https://api.qrserver.com/v1/create-qr-code/?data='.
- $data_to_qrcode.
- '&&size='.$options['size'].'x'.$options['size'].
- '&ecc='.$options['errorCorrectionLevel'].
- '&margin=0&color='.$options['foreground'].
- '&bgcolor='.$options['background'].
- '&qzone=2'.
- '&format='.$data_to_db['format'];
+ $outputInterface = QRGdImagePNG::class;
+ $imageFormat = strtolower($data_to_db['format']);
+ $fileExt = $imageFormat;
+ $forceBlackWhite = false;
- $content = file_get_contents($url);
-
- $filename = SAVED_QRCODE_DIRECTORY.$data_to_db['filename'].'.'.$data_to_db['format'];
-
- try{
- file_put_contents($filename, $content);
+
+ switch ($imageFormat)
+ {
+ case 'png':
+ $outputInterface = QRGdImagePNG::class;
+ $imageFormat = 'png';
+ break;
+ case 'gif':
+ $outputInterface = QRImagick::class;
+ $imageFormat = 'gif';
+ break;
+ case 'jpg':
+ $outputInterface = QRImagick::class;
+ $imageFormat = 'jpg';
+ break;
+ case 'jpeg':
+ $outputInterface = QRImagick::class;
+ $imageFormat = 'jpeg';
+ break;
+ case 'svg':
+ # $outputInterface = QRImagick::class;
+ $outputInterface = QRMarkupSVG::class;
+ $imageFormat = 'svg';
+ break;
+ case 'svgbw':
+ $outputInterface = QRMarkupSVG::class;
+ $imageFormat = 'svg';
+ $fileExt = 'svg';
+ $forceBlackWhite = true;
+ $data_to_db['format'] = $fileExt;
+ $data_to_db['qrcode'] = str_replace('.svgbw', '.svg', $data_to_db['qrcode']);
+ break;
+ case 'eps':
+ $outputInterface = QREps::class;
+ $imageFormat = 'eps';
+ break;
+ }
+
+
+ if(!file_exists(SAVED_QRCODE_DIRECTORY.$data_to_db['filename'].'.' . $fileExt)){
+ $eccLevel = constant(EccLevel::class.'::'.strtoupper($options['errorCorrectionLevel']));
+
+ $qroptions = new QROptions;
+ $qroptions->outputInterface = $outputInterface;
+ $qroptions->outputBase64 = false;
+ $qroptions->eccLevel = $eccLevel;
+ $qroptions->quietzoneSize = 2;
+
+ $moduleValues = [
+ // finder
+ QRMatrix::M_FINDER_DARK => $options['foreground'],
+ QRMatrix::M_FINDER_DOT => $options['foreground'],
+ QRMatrix::M_FINDER => $options['background'],
+ // alignment
+ QRMatrix::M_ALIGNMENT_DARK => $options['foreground'],
+ QRMatrix::M_ALIGNMENT => $options['background'],
+ // timing
+ QRMatrix::M_TIMING_DARK => $options['foreground'],
+ QRMatrix::M_TIMING => $options['background'],
+ // format
+ QRMatrix::M_FORMAT_DARK => $options['foreground'],
+ QRMatrix::M_FORMAT => $options['background'],
+ // version
+ QRMatrix::M_VERSION_DARK => $options['foreground'],
+ QRMatrix::M_VERSION => $options['background'],
+ // data
+ QRMatrix::M_DATA_DARK => $options['foreground'],
+ QRMatrix::M_DATA => $options['background'],
+ // darkmodule
+ QRMatrix::M_DARKMODULE => $options['foreground'],
+ // separator
+ QRMatrix::M_SEPARATOR => $options['background'],
+ // quietzone
+ QRMatrix::M_QUIETZONE => $options['background'],
+ ];
+
+ if(in_array($data_to_db['format'], ['png', 'jpg', 'gif'], true))
+ {
+ $moduleValues = array_map(function($v)
+ {
+ if(preg_match('/[a-f\d]{6}/i', $v) === 1)
+ {
+ return array_map('hexdec', str_split($v, 2));
+ }
+
+ return null;
+ }, $moduleValues);
+
+ $qroptions->moduleValues = $moduleValues;
}
- catch(Exception $e){
+ else
+ {
+ $moduleValues = array_map(function($v)
+ {
+ if(preg_match('/[a-f\d]{6}/i', $v) === 1)
+ {
+ return '#' . $v ;
+ }
+
+ return null;
+ }, $moduleValues);
+
+ $qroptions->moduleValues = $moduleValues;
+ }
+
+ if ($outputInterface === QRMarkupSVG::class)
+ {
+ $qroptions->version = 7;
+ // if set to false, the light modules won't be rendered
+ $qroptions->drawLightModules = true;
+ $qroptions->svgUseFillAttributes = false;
+ // draw the modules as circles isntead of squares
+ $qroptions->drawCircularModules = true;
+ $qroptions->circleRadius = 0.4;
+ // connect paths
+ $qroptions->connectPaths = true;
+ // keep modules of these types as square
+ $qroptions->keepAsSquare = [
+ QRMatrix::M_FINDER_DARK,
+ QRMatrix::M_FINDER_DOT,
+ QRMatrix::M_ALIGNMENT_DARK,
+ ];
+
+ if($forceBlackWhite)
+ {
+ $qroptions->drawLightModules = false;
+ $qroptions->drawCircularModules = false;
+ // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient
+ $qroptions->svgDefs = '
+
+
+
+
+ ';
+ }
+ else
+ {
+ // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient
+ $qroptions->svgDefs = '
+
+
+
+
+
+
+
+
+ ';
+ }
+ }
+ else
+ {
+ $qroptions->version = -1;
+ $qroptions->scale = 20;
+ $qroptions->quality = 83;
+ }
+
+ if ($outputInterface === QRImagick::class)
+ {
+ $qroptions->imagickFormat = $imageFormat;
+ $qroptions->returnResource = true;
+ $imagick = (new QRCodeEx($qroptions))->render(urldecode($data_to_qrcode));
+ $imagick->scaleImage($options['size'], $options['size'], true);
+ $content = $imagick->getImageBlob();
+ $imagick->destroy();
+ }
+ else
+ {
+ $content = (new QRCodeEx($qroptions))->render(urldecode($data_to_qrcode));
+ }
+
+ $filename = SAVED_QRCODE_DIRECTORY.$data_to_db['filename'].'.' . $fileExt;
+
+ try
+ {
+ file_put_contents($filename, $content);
+ if ($outputInterface !== QRImagick::class &&
+ $outputInterface !== QRMarkupSVG::class)
+ {
+ $imagick = new \Imagick(realpath($filename));
+ $imagick->resizeImage($options['size'], $options['size'], imagick::FILTER_LANCZOS, 1, false);
+ $imagick->writeImage($filename);
+ $imagick->destroy();
+ }
+ }
+ catch(Exception $e)
+ {
$this->failure($e->getMessage());
}
-
+
// If you want you can customiaddLogo($data_to_db['qrcode'], $options['optionlogo']);