From 2fbe746c950296eb01dd2ab39891bb86c1063023 Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Thu, 30 Jul 2026 15:21:29 +0400 Subject: [PATCH 1/6] style(models): normalize quote style in SQL GROUP_CONCAT expression (#4608) Signed-off-by: Travis Garrison Co-authored-by: Travis Garrison --- app/Models/Sale.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/Sale.php b/app/Models/Sale.php index 8c14d248d..4696310eb 100644 --- a/app/Models/Sale.php +++ b/app/Models/Sale.php @@ -1095,7 +1095,7 @@ class Sale extends Model SUM(CASE WHEN payments.cash_adjustment = 1 THEN payments.payment_amount ELSE 0 END) AS sale_cash_adjustment, SUM(payments.cash_refund) AS sale_cash_refund, GROUP_CONCAT(CONCAT(payments.payment_type, " ", (payments.payment_amount - payments.cash_refund)) SEPARATOR ", ") AS payment_type, - GROUP_CONCAT(NULLIF(payments.reference_code, '') SEPARATOR ", ") AS reference_code + GROUP_CONCAT(NULLIF(payments.reference_code, "") SEPARATOR ", ") AS reference_code FROM ' . $this->db->prefixTable('sales_payments') . ' AS payments INNER JOIN ' . $this->db->prefixTable('sales') . ' AS sales ON sales.sale_id = payments.sale_id From 89677cb8f2f5da8d69844cb1723166dd1740e3f3 Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:24:02 +0400 Subject: [PATCH 2/6] chore(deps): upgrade dompdf from v2.0.8 to v3.1.6 (#4610) - Update dompdf/dompdf constraint from ^2.0.3 to ^3.1.6 - Dependency names changed: phenx/php-font-lib and phenx/php-svg-lib replaced by dompdf/php-font-lib and dompdf/php-svg-lib ^1.0.0 - Remove ThirdParty/dompdf path from Autoload.php psr4 namespace map - Update composer.lock with new content hash and package references Signed-off-by: Travis Garrison Co-authored-by: Travis Garrison --- app/Config/Autoload.php | 3 +- composer.json | 2 +- composer.lock | 398 ++++++++++++++++++++++++++++------------ 3 files changed, 281 insertions(+), 122 deletions(-) diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index 073b39aab..3ad1105cb 100644 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -39,8 +39,7 @@ class Autoload extends AutoloadConfig */ public $psr4 = [ APP_NAMESPACE => APPPATH, - 'Config' => APPPATH . 'Config', - 'dompdf' => APPPATH . 'ThirdParty/dompdf/src' + 'Config' => APPPATH . 'Config' ]; /** diff --git a/composer.json b/composer.json index 4a457d250..7a876513a 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "php": "^8.2", "ext-intl": "*", "codeigniter4/framework": "4.7.2", - "dompdf/dompdf": "^2.0.3", + "dompdf/dompdf": "^3.1.6", "ezyang/htmlpurifier": "^4.17", "laminas/laminas-escaper": "2.18.0", "paragonie/random_compat": "^2.0.21", diff --git a/composer.lock b/composer.lock index 8df1b7ea5..77eee5efe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "eabbc14aefdea4c933869069d6eadadb", + "content-hash": "0f280c9536dc9d80d74b004b50c152a1", "packages": [ { "name": "codeigniter4/framework", @@ -85,32 +85,34 @@ }, { "name": "dompdf/dompdf", - "version": "v2.0.8", + "version": "v3.1.6", "source": { "type": "git", "url": "https://github.com/dompdf/dompdf.git", - "reference": "c20247574601700e1f7c8dab39310fca1964dc52" + "reference": "6d4b4eb8500f7a786da8868ba463a71b725a4005" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/dompdf/zipball/c20247574601700e1f7c8dab39310fca1964dc52", - "reference": "c20247574601700e1f7c8dab39310fca1964dc52", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/6d4b4eb8500f7a786da8868ba463a71b725a4005", + "reference": "6d4b4eb8500f7a786da8868ba463a71b725a4005", "shasum": "" }, "require": { + "dompdf/php-font-lib": "^1.0.0", + "dompdf/php-svg-lib": "^1.0.0", "ext-dom": "*", "ext-mbstring": "*", "masterminds/html5": "^2.0", - "phenx/php-font-lib": ">=0.5.4 <1.0.0", - "phenx/php-svg-lib": ">=0.5.2 <1.0.0", "php": "^7.1 || ^8.0" }, "require-dev": { + "ext-gd": "*", "ext-json": "*", "ext-zip": "*", "mockery/mockery": "^1.3", - "phpunit/phpunit": "^7.5 || ^8 || ^9", - "squizlabs/php_codesniffer": "^3.5" + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0" }, "suggest": { "ext-gd": "Needed to process images", @@ -141,9 +143,100 @@ "homepage": "https://github.com/dompdf/dompdf", "support": { "issues": "https://github.com/dompdf/dompdf/issues", - "source": "https://github.com/dompdf/dompdf/tree/v2.0.8" + "source": "https://github.com/dompdf/dompdf/tree/v3.1.6" }, - "time": "2024-04-29T13:06:17+00:00" + "time": "2026-07-20T12:29:38+00:00" + }, + { + "name": "dompdf/php-font-lib", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-font-lib.git", + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a6e9a688a2a80016ac080b97be73d3e10c444c9a", + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11 || ^12" + }, + "type": "library", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "The FontLib Community", + "homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/dompdf/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/1.0.2" + }, + "time": "2026-01-20T14:10:26+00:00" + }, + { + "name": "dompdf/php-svg-lib", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-svg-lib.git", + "reference": "8259ffb930817e72b1ff1caef5d226501f3dfeb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/8259ffb930817e72b1ff1caef5d226501f3dfeb1", + "reference": "8259ffb930817e72b1ff1caef5d226501f3dfeb1", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabberworm/php-css-parser": "^8.4 || ^9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The SvgLib Community", + "homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/dompdf/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/1.0.2" + }, + "time": "2026-01-02T16:01:13+00:00" }, { "name": "ezyang/htmlpurifier", @@ -269,16 +362,16 @@ }, { "name": "masterminds/html5", - "version": "2.10.0", + "version": "2.10.1", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "fcf91eb64359852f00d921887b219479b4f21251" + "reference": "fd5018f6815fff903946d0564977b44ce8010e29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251", - "reference": "fcf91eb64359852f00d921887b219479b4f21251", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fd5018f6815fff903946d0564977b44ce8010e29", + "reference": "fd5018f6815fff903946d0564977b44ce8010e29", "shasum": "" }, "require": { @@ -286,7 +379,7 @@ "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9 || ^10" }, "type": "library", "extra": { @@ -330,9 +423,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.10.0" + "source": "https://github.com/Masterminds/html5-php/tree/2.10.1" }, - "time": "2025-07-25T09:04:22+00:00" + "time": "2026-06-23T18:43:15+00:00" }, { "name": "paragonie/random_compat", @@ -388,96 +481,6 @@ }, "time": "2022-02-16T17:07:03+00:00" }, - { - "name": "phenx/php-font-lib", - "version": "0.5.6", - "source": { - "type": "git", - "url": "https://github.com/dompdf/php-font-lib.git", - "reference": "a1681e9793040740a405ac5b189275059e2a9863" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a1681e9793040740a405ac5b189275059e2a9863", - "reference": "a1681e9793040740a405ac5b189275059e2a9863", - "shasum": "" - }, - "require": { - "ext-mbstring": "*" - }, - "require-dev": { - "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "FontLib\\": "src/FontLib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Fabien Ménager", - "email": "fabien.menager@gmail.com" - } - ], - "description": "A library to read, parse, export and make subsets of different types of font files.", - "homepage": "https://github.com/PhenX/php-font-lib", - "support": { - "issues": "https://github.com/dompdf/php-font-lib/issues", - "source": "https://github.com/dompdf/php-font-lib/tree/0.5.6" - }, - "time": "2024-01-29T14:45:26+00:00" - }, - { - "name": "phenx/php-svg-lib", - "version": "0.5.4", - "source": { - "type": "git", - "url": "https://github.com/dompdf/php-svg-lib.git", - "reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/46b25da81613a9cf43c83b2a8c2c1bdab27df691", - "reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^7.1 || ^8.0", - "sabberworm/php-css-parser": "^8.4" - }, - "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Svg\\": "src/Svg" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Fabien Ménager", - "email": "fabien.menager@gmail.com" - } - ], - "description": "A library to read, parse and export to PDF SVG files.", - "homepage": "https://github.com/PhenX/php-svg-lib", - "support": { - "issues": "https://github.com/dompdf/php-svg-lib/issues", - "source": "https://github.com/dompdf/php-svg-lib/tree/0.5.4" - }, - "time": "2024-04-08T12:52:34+00:00" - }, { "name": "picqer/php-barcode-generator", "version": "v2.4.2", @@ -567,25 +570,35 @@ }, { "name": "sabberworm/php-css-parser", - "version": "v8.9.0", + "version": "v9.4.0", "source": { "type": "git", "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", - "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9" + "reference": "fd3bf9fb173e0df649bc4e3e0d088a1b2417c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9", - "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9", + "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/fd3bf9fb173e0df649bc4e3e0d088a1b2417c08f", + "reference": "fd3bf9fb173e0df649bc4e3e0d088a1b2417c08f", "shasum": "" }, "require": { "ext-iconv": "*", - "php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "^7.2.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "thecodingmachine/safe": "^1.3 || ^2.5 || ^3.4" }, "require-dev": { - "phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41", - "rawr/cross-data-providers": "^2.0.0" + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpstan/extension-installer": "1.4.3", + "phpstan/phpstan": "1.12.33 || 2.2.2", + "phpstan/phpstan-phpunit": "1.4.2 || 2.0.16", + "phpstan/phpstan-strict-rules": "1.6.2 || 2.0.11", + "phpunit/phpunit": "8.5.52", + "rawr/phpunit-data-provider": "3.3.1", + "rector/rector": "1.2.10 || 2.4.6", + "rector/type-perfect": "1.0.0 || 2.1.3", + "squizlabs/php_codesniffer": "4.0.1", + "thecodingmachine/phpstan-safe-rule": "1.2.0 || 1.4.3" }, "suggest": { "ext-mbstring": "for parsing UTF-8 CSS" @@ -593,10 +606,14 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "9.0.x-dev" + "dev-main": "9.5.x-dev" } }, "autoload": { + "files": [ + "src/Rule/Rule.php", + "src/RuleSet/RuleContainer.php" + ], "psr-4": { "Sabberworm\\CSS\\": "src/" } @@ -627,9 +644,9 @@ ], "support": { "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues", - "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0" + "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v9.4.0" }, - "time": "2025-07-11T13:20:48+00:00" + "time": "2026-06-18T15:10:53+00:00" }, { "name": "tamtamchik/namecase", @@ -694,6 +711,149 @@ "source": "https://github.com/tamtamchik/namecase/tree/3.0.0" }, "time": "2023-01-26T15:07:18+00:00" + }, + { + "name": "thecodingmachine/safe", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/safe.git", + "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/705683a25bacf0d4860c7dea4d7947bfd09eea19", + "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^10", + "squizlabs/php_codesniffer": "^3.2" + }, + "type": "library", + "autoload": { + "files": [ + "lib/special_cases.php", + "generated/apache.php", + "generated/apcu.php", + "generated/array.php", + "generated/bzip2.php", + "generated/calendar.php", + "generated/classobj.php", + "generated/com.php", + "generated/cubrid.php", + "generated/curl.php", + "generated/datetime.php", + "generated/dir.php", + "generated/eio.php", + "generated/errorfunc.php", + "generated/exec.php", + "generated/fileinfo.php", + "generated/filesystem.php", + "generated/filter.php", + "generated/fpm.php", + "generated/ftp.php", + "generated/funchand.php", + "generated/gettext.php", + "generated/gmp.php", + "generated/gnupg.php", + "generated/hash.php", + "generated/ibase.php", + "generated/ibmDb2.php", + "generated/iconv.php", + "generated/image.php", + "generated/imap.php", + "generated/info.php", + "generated/inotify.php", + "generated/json.php", + "generated/ldap.php", + "generated/libxml.php", + "generated/lzf.php", + "generated/mailparse.php", + "generated/mbstring.php", + "generated/misc.php", + "generated/mysql.php", + "generated/mysqli.php", + "generated/network.php", + "generated/oci8.php", + "generated/opcache.php", + "generated/openssl.php", + "generated/outcontrol.php", + "generated/pcntl.php", + "generated/pcre.php", + "generated/pgsql.php", + "generated/posix.php", + "generated/ps.php", + "generated/pspell.php", + "generated/readline.php", + "generated/rnp.php", + "generated/rpminfo.php", + "generated/rrd.php", + "generated/sem.php", + "generated/session.php", + "generated/shmop.php", + "generated/sockets.php", + "generated/sodium.php", + "generated/solr.php", + "generated/spl.php", + "generated/sqlsrv.php", + "generated/ssdeep.php", + "generated/ssh2.php", + "generated/stream.php", + "generated/strings.php", + "generated/swoole.php", + "generated/uodbc.php", + "generated/uopz.php", + "generated/url.php", + "generated/var.php", + "generated/xdiff.php", + "generated/xml.php", + "generated/xmlrpc.php", + "generated/yaml.php", + "generated/yaz.php", + "generated/zip.php", + "generated/zlib.php" + ], + "classmap": [ + "lib/DateTime.php", + "lib/DateTimeImmutable.php", + "lib/Exceptions/", + "generated/Exceptions/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP core functions that throw exceptions instead of returning FALSE on error", + "support": { + "issues": "https://github.com/thecodingmachine/safe/issues", + "source": "https://github.com/thecodingmachine/safe/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://github.com/OskarStark", + "type": "github" + }, + { + "url": "https://github.com/shish", + "type": "github" + }, + { + "url": "https://github.com/silasjoisten", + "type": "github" + }, + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2026-02-04T18:08:13+00:00" } ], "packages-dev": [ @@ -5386,5 +5546,5 @@ "ext-intl": "*" }, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } From 337cc098f29ee2fb81507a5ad09ef1092ebb1cee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:15:13 +0400 Subject: [PATCH 3/6] chore(deps): bump brace-expansion (#4614) Bumps and [brace-expansion](https://github.com/juliangruber/brace-expansion). These dependencies needed to be updated together. Updates `brace-expansion` from 1.1.12 to 1.1.18 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.18) Updates `brace-expansion` from 2.1.0 to 2.1.4 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.18) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 1.1.18 dependency-type: indirect - dependency-name: brace-expansion dependency-version: 2.1.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e5ed3b63..04c031f0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -917,9 +917,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -5262,9 +5262,9 @@ } }, "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { From 734c7d291c96b663602291b0b0bfc1b92f5777c0 Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:57:41 +0400 Subject: [PATCH 4/6] chore(deps): add xlsx via SheetJS CDN and upgrade tableexport plugin (#4615) - Add xlsx 0.20.3 from SheetJS CDN via package overrides - Bump tableexport.jquery.plugin from ^1.30.0 to ^1.33.0 - Add xlsx bundle to gulp JS pipeline before tableexport Signed-off-by: Travis Garrison Co-authored-by: Travis Garrison --- app/Views/reports/tabular.php | 2 +- app/Views/reports/tabular_details.php | 2 +- gulpfile.js | 2 + package-lock.json | 82 ++------------------------- package.json | 5 +- 5 files changed, 14 insertions(+), 79 deletions(-) diff --git a/app/Views/reports/tabular.php b/app/Views/reports/tabular.php index 02393513c..5bb0c102b 100644 --- a/app/Views/reports/tabular.php +++ b/app/Views/reports/tabular.php @@ -62,7 +62,7 @@ sortable: true, showExport: true, exportDataType: 'all', - exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel', 'pdf'], + exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'xlsx', 'pdf'], pagination: true, showColumns: true, data: , diff --git a/app/Views/reports/tabular_details.php b/app/Views/reports/tabular_details.php index 281b9e1b9..acc69ed06 100644 --- a/app/Views/reports/tabular_details.php +++ b/app/Views/reports/tabular_details.php @@ -67,7 +67,7 @@ uniqueId: 'id', showExport: true, exportDataType: 'all', - exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel', 'pdf'], + exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'xlsx', 'pdf'], data: , iconSize: 'sm', paginationVAlign: 'bottom', diff --git a/gulpfile.js b/gulpfile.js index 5a0ead6a7..9052a513f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -123,6 +123,7 @@ gulp.task('debug-js', function() { './node_modules/jspdf/dist/jspdf.umd.js', './node_modules/dompurify/dist/purify.js', './node_modules/jspdf-autotable/dist/jspdf.plugin.autotable.js', + './node_modules/xlsx/dist/xlsx.full.min.js', './node_modules/tableexport.jquery.plugin/tableExport.min.js', './node_modules/chartist/dist/chartist.js', './node_modules/chartist-plugin-pointlabels/dist/chartist-plugin-pointlabels.js', @@ -172,6 +173,7 @@ gulp.task('prod-js', function() { './node_modules/chartist-plugin-axistitle/dist/chartist-plugin-axistitle.min.js', './node_modules/chartist-plugin-tooltips/dist/chartist-plugin-tooltip.min.js', './node_modules/chartist-plugin-barlabels/dist/chartist-plugin-barlabels.min.js', + './node_modules/xlsx/dist/xlsx.full.min.js', './node_modules/tableexport.jquery.plugin/tableExport.min.js'], { allowEmpty: true }); var opensourcepos2js = gulp.src(['./node_modules/bootstrap-daterangepicker/daterangepicker.js', diff --git a/package-lock.json b/package-lock.json index 04c031f0e..e22e7bc3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "jquery-validation": "^1.19.5", "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.7", - "tableexport.jquery.plugin": "^1.30.0" + "tableexport.jquery.plugin": "^1.33.0" }, "devDependencies": { "gulp": "^5.0.1", @@ -313,14 +313,6 @@ "node": ">=6.5" } }, - "node_modules/adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", @@ -1075,18 +1067,6 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "optional": true }, - "node_modules/cfb": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", - "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", - "dependencies": { - "adler-32": "~1.3.0", - "crc-32": "~1.2.0" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -1325,14 +1305,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/codepage": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", - "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/coffeescript": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.7.0.tgz", @@ -1461,6 +1433,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, "bin": { "crc32": "bin/crc32.njs" }, @@ -2119,14 +2092,6 @@ "node": ">= 18" } }, - "node_modules/frac": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", - "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/fs-mkdirp-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", @@ -5483,17 +5448,6 @@ "node": ">= 0.10" } }, - "node_modules/ssf": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", - "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", - "dependencies": { - "frac": "~1.1.2" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/stackblur-canvas": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz", @@ -6545,22 +6499,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wmf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", - "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/word": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", - "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/wordwrapjs": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz", @@ -6721,18 +6659,10 @@ "dev": true }, "node_modules/xlsx": { - "version": "0.18.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", - "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", - "dependencies": { - "adler-32": "~1.3.0", - "cfb": "~1.2.1", - "codepage": "~1.15.0", - "crc-32": "~1.2.1", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - }, + "version": "0.20.3", + "resolved": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", + "integrity": "sha512-oLDq3jw7AcLqKWH2AhCpVTZl8mf6X2YReP+Neh0SJUzV/BdZYjth94tG5toiMB1PPrYtxOCfaoUCkvtuH+3AJA==", + "license": "Apache-2.0", "bin": { "xlsx": "bin/xlsx.njs" }, diff --git a/package.json b/package.json index 4503cadcc..eaeeea6eb 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,10 @@ "jquery-validation": "^1.19.5", "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.7", - "tableexport.jquery.plugin": "^1.30.0" + "tableexport.jquery.plugin": "^1.33.0" + }, + "overrides": { + "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz" }, "devDependencies": { "gulp": "^5.0.1", From 8e465f9256f51f7d148886468f11d8cf35be39db Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:58:50 +0400 Subject: [PATCH 5/6] chore(deps): bump lodash.template from 4.5.0 to 4.18.1 (#4616) Signed-off-by: Travis Garrison Co-authored-by: Travis Garrison --- package-lock.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e22e7bc3c..2876b2e7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4334,10 +4334,12 @@ "license": "MIT" }, "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.18.1.tgz", + "integrity": "sha512-5urZrLnV/VD6zHK5KsVtZgt7H19v51mIzoS0aBNH8yp3I8tbswrEjOABOPY8m8uB7NuibubLrMX+Y0PXsU9X+w==", + "deprecated": "This package is deprecated. Use https://socket.dev/npm/package/eta instead.", "dev": true, + "license": "MIT", "dependencies": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" From cdf477f82308d4b6e4001e6e92b522d8d236a1e2 Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Wed, 5 Aug 2026 11:48:05 +0400 Subject: [PATCH 6/6] fix(login): skip auth validation on new install to allow migration (#4609) * fix(login): skip auth validation on new install to allow migration On fresh installs with no DB version, login validation would fail before migrations could run. Check MY_Migration::getCurrentVersion() and bypass credential check when no version exists. Signed-off-by: Travis Garrison * fix(login): distinguish DB unavailable from empty install `getCurrentVersion()` previously returned `int` with 0 used for both \"empty database\" and \"DB connection failure\". This conflated two distinct states, causing login to skip auth when DB was unreachable. Changes: - Return type widened to `?int`: null = DB unavailable, 0 = confirmed empty DB (new install), positive int = migrated - Login controller now returns 503 on null (DB error) before checking isNewInstall - isNewInstall gate now uses `=== 0` instead of falsy check Signed-off-by: Travis Garrison * fix(login): return 503 JSON response when DB connection unavailable Extract getCurrentVersion() before building data array to distinguish null (connection failure) from 0 (new install). Return early with JSON 503 when DB is unreachable instead of rendering broken view. Update return type hint to include ResponseInterface. Signed-off-by: Travis Garrison --------- Signed-off-by: Travis Garrison Co-authored-by: Travis Garrison Co-authored-by: jekkos --- app/Controllers/Login.php | 55 ++++++++++++++++++++++++---------- app/Libraries/MY_Migration.php | 9 +++--- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/app/Controllers/Login.php b/app/Controllers/Login.php index fae1f5e83..df88371b5 100644 --- a/app/Controllers/Login.php +++ b/app/Controllers/Login.php @@ -18,9 +18,9 @@ class Login extends BaseController public Model $employee; /** - * @return RedirectResponse|string + * @return RedirectResponse|ResponseInterface|string */ - public function index(): string|RedirectResponse + public function index(): string|RedirectResponse|ResponseInterface { $this->employee = model(Employee::class); if (!$this->employee->is_logged_in()) { @@ -33,13 +33,24 @@ class Login extends BaseController $migration->migrateToCI4(); + $currentVersion = MY_Migration::getCurrentVersion(); + + if ($currentVersion === null) { + return $this->response->setJSON([ + 'success' => false, + 'message' => lang('Login.migration_error_connection') + ])->setStatusCode(503); + } + + $latestVersion = $migration->getLatestMigration(); + $validation = Services::validation(); $data = [ 'hasErrors' => false, - 'isNewInstall' => !(MY_Migration::getCurrentVersion()), - 'isLatest' => $migration->isLatest(), - 'latestVersion' => $migration->getLatestMigration(), + 'isNewInstall' => $currentVersion === 0, + 'isLatest' => $latestVersion === $currentVersion, + 'latestVersion' => $latestVersion, 'gcaptchaEnabled' => $gcaptchaEnabled, 'config' => $config, 'validation' => $validation @@ -76,19 +87,33 @@ class Login extends BaseController public function migrate(): ResponseInterface { - $rules = ['username' => 'required|login_check[data]']; - $messages = [ - 'username' => [ - 'required' => lang('Login.required_username'), - 'login_check' => lang('Login.invalid_username_and_password'), - ] - ]; + $currentVersion = MY_Migration::getCurrentVersion(); - if (!$this->validate($rules, $messages)) { + if ($currentVersion === null) { return $this->response->setJSON([ 'success' => false, - 'message' => lang('Login.invalid_username_and_password') - ])->setStatusCode(401); + 'message' => lang('Login.migration_error_connection') + ])->setStatusCode(503); + } + + // Only a confirmed empty database counts as a new install with no credentials to check. + $isNewInstall = $currentVersion === 0; + + if (!$isNewInstall) { + $rules = ['username' => 'required|login_check[data]']; + $messages = [ + 'username' => [ + 'required' => lang('Login.required_username'), + 'login_check' => lang('Login.invalid_username_and_password'), + ] + ]; + + if (!$this->validate($rules, $messages)) { + return $this->response->setJSON([ + 'success' => false, + 'message' => lang('Login.invalid_username_and_password') + ])->setStatusCode(401); + } } try { diff --git a/app/Libraries/MY_Migration.php b/app/Libraries/MY_Migration.php index 3ded91735..a1bf1f256 100644 --- a/app/Libraries/MY_Migration.php +++ b/app/Libraries/MY_Migration.php @@ -32,9 +32,10 @@ class MY_Migration extends MigrationRunner /** * Gets the database version number * - * @return int The version number of the last successfully run database migration. + * @return int|null The version number of the last successfully run database migration, + * 0 for a confirmed empty database, or null if the database is unavailable. */ - public static function getCurrentVersion(): int + public static function getCurrentVersion(): ?int { try { $db = Database::connect(); @@ -45,9 +46,9 @@ class MY_Migration extends MigrationRunner return $result ? (int) $result->version : 0; } } catch (Exception $e) { - // Database not available yet (e.g. fresh install before schema). + // Database unavailable — distinct from a confirmed empty database. // Catches mysqli_sql_exception which is not a DatabaseException. - return 0; + return null; } return 0;