[v1.5.0] (2026-11-02)
Major Features
- Release script –
scripts/release.shno longer copies the[Unreleased]placeholder line into the new release section, and keeps a blank line after the version heading. - OPcache status + fresh Docker base – About → Key PHP extensions showed OPcache as missing because the extension registers as
Zend OPcache; it now checks that name and reports whether the opcode cache is actually enabled (opcache_get_status()), since PHP 8.5 always loads it (includes/about_info.php). OPcache was already on in the container (opcache.enable=1in theDockerfile).docker-pushimage.shnow builds with--pullso images always use the currentphp:8.5-apachebase (a cached older base could fall below the PHP 8.5.12 minimum). - GitLab releases – Version tags now get a GitLab Release as well as the GitHub one. New
gitlab-releasejob in.gitlab-ci.yml(tagvX.Y.Z,glabimage,CI_JOB_TOKEN) uses the## [vX.Y.Z]section ofCHANGELOG.mdviascripts/extract_changelog_section.shas release notes, and runs independently of the Docker job.scripts/release.shpushes the branch and tag to thegitlabremote too (override withGITLAB_REMOTE; skipped if the remote is missing), including in--publish-only.AGENTS.mdupdated. - Square logo + README header – Added a 1:1 project logo in the green dice / RAND style of the social preview:
images/logo.png(1024×1024, rendered with Ubuntu Bold) and editable sourceimages/logo.svg. Removed the pinkdocs/images/banner-gradient.pngbanner from the top ofREADME.md; the social preview is now the first image. - Filled buttons (global toggle) – Action buttons that used
btn-outline-*are now filled (btn-primary,btn-light, …). One setting controls it:BTN_OUTLINEinincludes/config.php(false= filled,true= outline), applied through the newbtnClass()helper in PHP (includes/functions.php) and JS (js/rand.js, readswindow.RAND_BTN_OUTLINEset inindex.php). Radio toggle groups (btn-checklabels: logo format/shape, number mode, relative-time style) intentionally stay outline so the selected option remains visible. Copy-button feedback now restores the button's original classes instead of hard-coding the outline variant, andindex.php'scopyToClipboard()reusessetCopyButtonFeedback(). - Minimum PHP 8.5.12 –
composer.jsonnow requiresphp >=8.5.12, so Composer's generatedvendor/composer/platform_check.phpstops the app with a clear error on older PHP. README requirements and apt example moved to PHP 8.5 (php8.5-*). The Docker image (php:8.5-apache, currently 8.5.12) already meets it. - Composer dependencies – Updated all PHP packages to latest: chillerlan/php-qrcode
5.0.5→6.0.1(major), symfony/yaml7.4.8→8.1.10(major), dragonmantank/cron-expression3.6.0→3.6.1, symfony/polyfill-ctype1.33.0→1.37.0, chillerlan/php-settings-container3.2.1→3.3.0(4.x is blocked by php-qrcode's^3.2.1);symfony/deprecation-contractsis no longer needed.includes/qrcode.phpnow uses php-qrcode 6'soutputInterface => QRGdImagePNG::class(theoutputType/GDIMAGE_PNGoption was removed); generated PNGs are byte-identical to before. symfony/yaml 8 needs PHP 8.4.1+; see the PHP minimum entry below. - Axios 1.21.0 – Bumped bundled
js/axios.min.js(+ source map) from1.11.0to1.21.0, taken from the npm tarball and checked against its published sha512 integrity. - About → External libraries – The About modal now lists third-party libraries with their versions, type (Frontend / PHP) and source in a table.
getAboutDependencies()(includes/about_info.php) reads them from the files that load them — CDN tags inindex.php, lazy loaders injs/rand.js(resolving*_VERSIONconstants), bundledjs/*.min.jsbanners and Composer'svendor/composer/installed.json(falls back tocomposer.lock) — so versions stay in sync with no manual list. Rendered inrenderAboutInfo()(js/rand.js). - Lucide icons – Replaced Bootstrap Icons with the Lucide icon font (
lucide-static@1.66.0CDN CSS) inindex.phpandtest_random_buttons.html. Sharedicon()helper now emitsicon-<name>(witharia-hidden); every call site inmodules/,includes/,gen.phpandjs/rand.jswas renamed to its Lucide equivalent (e.g.files→copy,arrow-repeat→refresh-cw,speedometer2→gauge). Lucide has no brand marks, so GitHub usesgit-forkand the browser inspector usesapp-window. Base alignment rule for[class^="icon-"]added tostyle.css. - String Tools output – Output is now a read-only textarea matching the input box instead of a green result card (
modules/string_tools.php).handle_stringtoolsreturns plain text (exact whitespace, HTML shown literally instead of rendered) and answers validation errors with HTTP 422, shown in a status area under the output. SharedcopyToClipboard()(index.php) now copies the live.valueof textarea/input targets. - Tabler 1.7.3 – Bumped
@tabler/coreCDN CSS/JS from1.4.0to1.7.3inindex.php(and thetest_*.htmlharness pages). - Shuffle-button fields – Inputs/textareas wrapped in
.input-with-random-btnno longer shrink to 500px while focused (global.form-control:focuscap out-ranked the wrapper's stretch rule instyle.css). String Tools output textarea usesrand-code-textareato span its column. - Syntax Highlighter – New Text & Data → Syntax Highlighter tool (
modules/syntax_highlight.php) using highlight.js 11.12.0: paste code, auto-detect language or override from the full language list (packs load in the background for better detection), dark/light theme toggle (persisted), live preview, Copy plain and Copy rich (Word/OneNote) (inline-styled HTML via clipboard; buttons sit in a top toolbar inside the preview). Shared CDN helpers injs/rand.js(ensureHighlightJsAssets, lazy language packs); Markdown asset loader bumped to the same highlight.js version. - Docker publish sync (Hub + GHCR) –
docker-pushimage.shnow builds once andbuildx --pushes the same tags to Docker Hub and GHCR; login/push failure on an enabled registry aborts (no more Hub-only “success” when GHCR was supposed to publish). GitLab CI docs note the fail-closed sync guarantee. Synced existing Hub → GHCR tags (:latest/:v1.4.0/:1.4.0identical digests;:dev/:developidentical config+layers) and added missing Hub:1.4.0. - Repo social preview – Added GitHub-sized (
1280×640) social cards inimages/social-preview.png(dark) andimages/social-preview-light.png(light); dark variant shown at the top ofREADME.md. - Subnet Mask Calculator – IP field accepts pasted CIDR (
10.0.0.0/20); Bootstrapinput-groupwith appended/prefixsyncs bidirectionally with the subnet mask field. Server also accepts IP+CIDR when the subnet field is empty (handle_ip_parse_ipv4_optional_cidr()). Single shared shuffle button for the IP/prefix/mask block (data-shared-random); random samples vary the mask, not only/24. - CIDR to Range – Result table now includes the dotted Subnet mask (e.g.
/20→255.255.240.0), derived via existinghandle_ip_normalize_subnet_mask(). - Module subnav (subpages) – Multi-card tool pages now show a pill-style subnav bar that splits tools into individual subpages. Affected modules: Networking (DNS Lookup, CIDR→Range, Range→CIDR, Subnet Calculator, IP/Hex), Date & Time (Time Converter, Relative Time, Current Time), Private/Public Keys (Key Generator, Sign/Verify), SSH Key Generator (Generate, Verify). Active subtab is persisted in localStorage and deep-linkable via hash (e.g.
#networking/dns). New CSS classes.module-subnav,.subnav-pill,.subnav-panel; JS helpersinitModuleSubnav()/activateSubtab(); light-theme variant included. - Relative Time Calculator – New Date & Time → Relative Time subpage (
#datetime/relative) converts absolute dates/unix timestamps to human phrases (“3 hours ago”), evaluates relative expressions (2 days ago,+3 hours,next Monday) or amount+unit offsets into absolute times, and diffs two moments with a calendar breakdown. Handlerhandle_relative_time; helpers inincludes/tooling_helpers.php; shuffle samples injs/rand.js. - SSH key verify – Auto-detect of OpenSSH one-line public keys no longer fails with
preg_match(): Unknown modifierwhen the Base64 blob contains/(fixed delimiter incrypto_classify_verify_public_key()). - Docker (GitLab CI) – Image publish moved to
gitlab01(.gitlab-ci.yml): pushdev→:dev/:develop; push version tag →:latest+:vX.Y.Z(+ stripped) on Docker Hub + GHCR viadocker-pushimage.sh. Local pre-push Docker hook removed;./scripts/install-git-hooks.shclears oldcore.hooksPath. GitHub Actions Docker workflows stay unused. Local./docker-pushimage.shremains as fallback. - Docker (local publish workflow) –
./docker-pushimage.shmodes:--dev,--release [vX.Y.Z],--dry-run; envSKIP_DOCKERHUB/SKIP_GHCR. GHCR login failure no longer aborts after a successful Hub push. Docs updated inREADME.md,AGENTS.md,docker-image.config. - SSH / keypair PEM export – Leaving the passphrase empty now exports a truly unencrypted private key (
BEGIN PRIVATE KEY). Previously an empty string was passed toopenssl_pkey_export, which producedBEGIN ENCRYPTED PRIVATE KEYwith an empty password and causedssh-addto prompt for a passphrase. Generate forms (SSH, keypair, CSR) now use an explicit Protect private key with a passphrase switch (off by default) via sharedcrypto_passphrase_field_html()/crypto_req_optional_passphrase(). - String Generator – Added an Alphanumeric character-set option (
0-9a-zA-Z). Default sets remain Numbers, Lowercase, and Uppercase; Alphanumeric is hidden and disabled when any set other than Numbers is selected. Sharedstringgen_charset_chars()builds the pool for both generators; possible-combinations info now uses the real pool size. - Base Converter – Convert From defaults to Auto-detect (still overridable). Shared
detect_convert_any_selector()picks text / base64 / common numeric bases from the input; result heading shows the detected source. Also fixed “Invalid source/target format” for bases the UI already offered viais_convert_any_selector(). - Docker (local publish) –
docker-pushimage.shsupportsSKIP_DOCKERHUB=1for GHCR-only pushes when GitHub Actions are disabled, falls back togh auth tokenwhenGITHUB_TOKENis unset, and publishes the stripped version tag (e.g.1.4.0) to match CI. GHCR success message now only lists tags that were actually pushed. - Docker (GHCR auth) – Stale
GITHUB_TOKENin.env.localno longer blocks GHCR: login retries withgh auth token(viaenv -u GITHUB_TOKEN) and uses the live GitHub username fordocker login. - Unit Converter (Data) – Added SI bit units kilobit (kb)–terabit (Tb) and binary bit units kibibit (Kib)–tebibit (Tib); From-unit select groups options as Bits/Bytes × decimal/binary via reusable
groups+<optgroup>support (modules/units.php). - Calculator clipboard – Keyboard-first copy/paste: Ctrl/Cmd+C copies the current result, Ctrl/Cmd+V pastes a number or valid expression (
+ - * /, precedence-aware, noeval). Clicking the display also copies; invalid pastes show Error. - Crypto helpers (PHPStan) –
crypto_signature_digest_for_key()PHPDoc now acceptsOpenSSLAsymmetricKey|resource, matching PHP 8+ OpenSSL key objects and sibling helpers.