Skip to content

PNLCS 1.5.0

Choose a tag to compare

@Panelica Panelica released this 13 Oct 16:38
· 83 commits to main since this release

The stable release, offered to every installation. It contains everything in
1.5.0-beta.1 and 1.5.0-beta.2 (below), and the changes listed here, which
were made after 1.5.0-beta.2.

Added

  • Charge in the invoice's billing currency for Stripe, Mollie and PayPal,
    off by default (each gateway's settings under Setup β†’ Payment
    Gateways
    ). A customer billed in their own currency (Setup β†’
    Currencies
    ) is charged the amount the invoice shows, at the invoice's own
    rate, instead of the shop currency converted by their bank. Thank you,
    @ertugrulkeyvan.
  • Free subdomains for hosting orders (Setup β†’ General β†’ Domains): a
    hosting order can take a name under one of the shop's own domains, such as
    yourname.example-sites.com, instead of a domain of its own. Reserved
    names (www, mail, ns1, autodiscover, admin and more, or your own
    list) and names another service already has are refused. The parent domains
    need a wildcard DNS record; see Selling domains.
    Thank you, @ertugrulkeyvan.
  • The shop's social media profiles (Setup β†’ General β†’ Search engines
    and sharing
    ): X, Facebook, Instagram, LinkedIn, YouTube, TikTok, Threads
    and Medium. The default home page footer links to them and the home page
    names them to search engines; nothing is added until a profile is set.
    Thank you, @ertugrulkeyvan.
  • aaPanel server module for Sub aaPanel accounts: create, suspend,
    unsuspend, terminate, password and package changes, disk and bandwidth
    usage, and Login to panel. It needs aaPanel Pro with Sub aaPanel
    installed; see aaPanel hosting accounts. The
    connection test, the package list and an unlicensed panel's refusal were
    checked on aaPanel 8.0.6 with Sub aaPanel 3.0.4; account changes have not
    yet been run against a licensed panel. Thank you,
    @Alex9001.
  • Panelica mail certificate help: when the certificate for a customer's
    mail host could not be issued, their email page lists the DNS records it
    needs and offers to try again. Thank you,
    @ertugrulkeyvan.
  • Spanish has every text of the language files, addressing the reader as
    "usted". Thank you, @wmedia.
  • German client area and email texts, and all 32 email templates, from
    Dejan Wolf (WHOST, Austria), in the formal "Sie" the German translation
    uses.

Changed

  • Email templates in a new language start from the templates shipped for
    it (German and Polish) instead of copies of the English ones.
  • Panelica mail host: mail apps are told mail.<customer's domain>, the
    name the panel's certificate is for, or the host name the panel gives the
    certificate; before, they were told a name built from the server's
    hostname. The first mailbox of a domain asks the panel for that
    certificate when it has none. Thank you,
    @ertugrulkeyvan.
  • Panelica "Login to panel" opens the panel by the server's host name
    when the panel runs behind NAT, instead of an internal address the browser
    cannot reach. Thank you, @ertugrulkeyvan.
  • The language in the address: links in the core views and the flavor
    and aurora themes carry the page's language, so no redirect is needed; the
    language switcher adds ?lang only on the way back to the default
    language; a file at the root (/sw.js, /manifest.json, a verification
    file) keeps one address in every language. Thank you,
    @ertugrulkeyvan.
  • Admin screens: about 100 texts on 37 admin screens that showed English
    in every language are translated. Thank you,
    @ertugrulkeyvan.
  • Updates: when an update stops because the container runs an older
    panelica/pnlcs-runtime image, the page and pnlcs:update also say how
    Panelica replaces it (Docker Manager β†’ Update to the new tag).

Fixed

  • iyzico: an invoice billed in lira is charged the lira amount the
    invoice shows, not today's conversion of it. Thank you,
    @ertugrulkeyvan.
  • Hosting tabs: when the hosting control panel does not answer, the
    customer gets a message instead of a "Server Error" page; after a form the
    panel may already have carried out, they are told to check before trying
    again. Thank you, @ertugrulkeyvan.
  • Products: a product or product group named like an existing one gets
    an address of its own (vps-s-2) and can be ordered; before, its order
    link opened the other product or gave a 404, and a second group with the
    same name could not be saved. Thank you,
    @ertugrulkeyvan.
  • Products: saving a product that has no module no longer gives it
    Panelica's default limits, so the price list no longer shows resources
    nobody chose. Thank you, @ertugrulkeyvan.
  • Automation status: the page lists the scheduled tasks (it showed none),
    and on the Docker image it says the scheduler already runs inside the
    container instead of asking for a host cron line. The cron note says
    "every minute", which is what the line does.
  • Updates: a check or update request that the scheduler picked up but
    that never finished no longer leaves the page waiting for ever; it says the
    request was lost, also on a page that was kept open. Thank you,
    @ertugrulkeyvan.
  • Search engines and sharing: a page that writes its own sharing tags,
    such as a blog post, no longer gets a second set from the layout. Thank
    you, @ertugrulkeyvan.

Security

  • PayPal: a capture is credited only in the currency the shop charges in,
    or the invoice's billing currency when that option is on. Before, a capture
    of 100 in a currency worth far less than the shop's (100 HUF against a
    100.00 USD invoice) could mark the invoice paid. Thank you,
    @ertugrulkeyvan.
  • Two-factor setup draws its QR code on the server. The setup address,
    which carries the shared secret, is no longer sent to an outside QR
    service. Thank you, @ertugrulkeyvan.

Database changes

  • 2026_10_10_000001_ship_translated_email_templates: a German or Polish
    email template that you have not made your own and that is still exactly
    the English text gets the shipped translation, its subject and its message
    each on their own. A field you wrote yourself stays.
  • 2026_10_12_000001_give_products_with_a_shared_slug_their_own: a product
    whose slug is empty or already used by an older product gets one of its own
    (vps-s-2, vps-s-3), so its order address changes; the oldest keeps its
    slug, and every other product is untouched.

For theme and module authors

  • social_profiles() returns the profiles that are set (network => address);
    the new partial partials/social-links draws them as icon links.
  • A page that writes its own sharing tags sets @section('seo_own', '1');
    the layout then prints neither partials/seo-meta nor
    partials/locale-alternates for it. Themes
    lists the sections the layout reads.
  • Write links as url('/path'), not as plain paths, so they keep the page's
    language when the language is in the address.
  • The two-factor setup views receive $qrImage, an SVG data URI; $qrUrl
    is still passed, so an overriding view keeps working until it switches.
  • New server module aapanel (modules/Servers/AaPanel).

Views a theme may override that changed

  • resources/views/admin/affiliates/show.blade.php,
    admin/auth/enable-two-factor.blade.php, admin/calendar/index.blade.php,
    admin/clients/edit.blade.php, admin/clients/show.blade.php,
    admin/config/addon-output.blade.php, admin/config/automation.blade.php,
    admin/config/billable-items.blade.php, admin/config/bundles.blade.php,
    admin/config/custom-fields.blade.php,
    admin/config/domain-pricing.blade.php, admin/config/gateways.blade.php,
    admin/config/notifications.blade.php, admin/config/promotions.blade.php,
    admin/config/servers.blade.php, admin/config/ticket-escalation.blade.php,
    admin/config/ticket-spam.blade.php, admin/config/updates.blade.php,
    admin/domains/index.blade.php, admin/domains/show.blade.php,
    admin/invoices/create.blade.php, admin/invoices/show.blade.php,
    admin/layouts/app.blade.php, admin/logs/module.blade.php,
    admin/orders/show.blade.php, admin/products/create.blade.php,
    admin/products/create-group.blade.php, admin/products/edit.blade.php,
    admin/projects/create.blade.php, admin/projects/edit.blade.php,
    admin/projects/index.blade.php, admin/projects/show.blade.php,
    admin/quotes/create.blade.php, admin/quotes/edit.blade.php,
    admin/quotes/show.blade.php, admin/reports/show.blade.php,
    admin/settings/appearance.blade.php, admin/settings/general.blade.php,
    admin/ssl/show.blade.php, admin/whois.blade.php.
  • resources/views/client/auth/enable-two-factor.blade.php,
    client/cart/configure.blade.php, client/layouts/app.blade.php,
    client/services/hosting/email.blade.php,
    client/services/show.blade.php, client/tickets/create.blade.php.
  • resources/views/errors/403.blade.php, errors/404.blade.php,
    errors/500.blade.php, partials/locale-alternates.blade.php,
    partials/seo-meta.blade.php, sections/domain-search.blade.php,
    sections/footer.blade.php, sections/hosting-plans.blade.php,
    sections/navigation.blade.php, sections/styles.blade.php,
    sections/topbar.blade.php, sections/vps-plans.blade.php.
  • themes/aurora/views/sections/hero.blade.php,
    themes/aurora/views/sections/navigation.blade.php,
    themes/flavor/views/client/layouts/app.blade.php,
    themes/flavor/views/sections/footer.blade.php,
    themes/flavor/views/sections/navigation.blade.php.

Also in 1.5.0: from 1.5.0-beta.2

Added

  • Product mapping in the WHMCS importer. The services mapper maps each
    WHMCS product to a PNLCS product; an unmapped one is still matched by name.
    Two services on the same domain (hosting and e-mail, a VPS and its
    maintenance) are imported as two services, and each client gets a note
    listing their WHMCS services, so the result can be checked against the
    source. A re-import updates the services 1.4.0 imported instead of copying
    them. Thank you, @hedon77.
  • The language in the address, off by default (Setup β†’ Languages β†’
    Settings
    ). The default language keeps today's addresses; every other
    active language is served under its code (/en/client/store), so search
    engines can index every language and a shared link opens in the language it
    was copied in. Social sign-in and the e-mail confirmation link keep their
    own addresses. Thank you,
    @ertugrulkeyvan.
  • Search engines and link previews (Setup β†’ General β†’ Search engines
    and sharing
    ): a description on every client-facing page, Open Graph and X
    card tags so a shared link shows a title, text and image, and a sitemap at
    /sitemap.xml that updates itself. /robots.txt can be edited there once
    the shipped public/robots.txt file is removed; while the file is there,
    the web server answers with it as before. Thank you,
    @ertugrulkeyvan.
  • Tracking codes and a cookie consent bar (Setup β†’ General β†’ Tracking
    and cookie consent
    ): a Google Tag Manager container with Google Consent
    Mode v2, so ads and analytics wait for the visitor's consent, a consent bar
    where "necessary cookies only" is as easy as "accept", and code for the
    head and the end of every page. Nothing is added to a page until something
    is set. Thank you, @ertugrulkeyvan.
  • A number format per currency (Setup β†’ Currencies): 1,234.56,
    1.234,56, 1 234,56 or 1234.56. Every currency keeps 1,234.56 until
    you choose otherwise; the cart's running totals follow the format too.
    Thank you, @ertugrulkeyvan.
  • A promotion code in a link: any page opened with ?promo=CODE (or
    ?promocode=CODE, as WHMCS links write it) remembers the code, and the cart
    applies it once it holds a product the code is for. Every promotion rule
    still applies, and a code the customer typed is never replaced. Thank you,
    @ertugrulkeyvan.

Changed

  • Translations. The progress under Setup β†’ Languages counts a text as
    translated only when it is no longer the English text, and Translate
    missing
    now also translates texts still in English (names that stay the
    same, such as Stripe, are not sent again). About 460 texts of the client
    hosting pages, the e-mail setup guide, the SSL page and the home page's apps
    section were missing in German, Polish and Chinese; they are translated,
    with a few German machine-translation mistakes corrected. English, Turkish,
    German, Polish and Chinese are complete; a text a community language does
    not have yet shows in English.
  • Domain availability is checked through the registrar assigned to each
    domain extension, with the default registrar's bulk check kept for the
    rest. Thank you, @terbora-core.
  • The client page shows the client's information and billing identity in
    one panel. Thank you, @hedon77.

Fixed

  • Invoices: the "All" tab and the "All invoices" menu entry list paid and
    unpaid invoices; the list still opens on Unpaid. Thank you,
    @ertugrulkeyvan.
  • Stripe: the pay button names the currency ("Pay €12.00 by card"); the
    amount sent to Stripe is unchanged. Thank you,
    @ertugrulkeyvan.
  • Updates: clicking Update now right after a check finished could be
    refused with "the updater is busy" - the page said "ready" while the
    updater was still cleaning up. The page now says so only once it is done.

For developers

  • Every language file is checked before it ships: it loads, keeps every
    placeholder the English text declares, and carries exactly the English
    markup. The community languages are reported, not enforced, so adding an
    English text no longer requires writing it in 25 languages.
    Translations explains what is checked,
    texts that stay the same as English and how a language becomes complete;
    translators are credited in the README.

Database changes

  • whmcs_import_profiles.product_mapping (JSON, nullable) and
    services.whmcs_product_name (string, nullable): new columns.
  • 2026_10_09_000001_drop_translation_rows_now_shipped_in_files: the texts
    above used to be delivered as rows of dynamic_translations; they now ship
    in the language files, and a row that says exactly what the file says is
    removed (it would hide later corrections to the file). A text you changed
    yourself is different from the file and stays. What the pages show does
    not change.

For theme and module authors

  • New hook point SitemapUrls: return addresses (strings, or
    ['loc' => ..., 'lastmod' => ...]) to add your public pages to the sitemap.
  • Client layouts should print ClientAreaHeadOutput and
    ClientAreaFooterOutput (the tracking codes and the consent bar use them);
    the flavor theme now does.
  • New view partials: partials/seo-meta, partials/locale-alternates,
    partials/consent-bar, and the sitemap view.

Views a theme may override that changed

  • resources/views/admin/clients/show.blade.php,
    admin/config/currencies.blade.php, admin/config/languages/index.blade.php,
    admin/invoices/index.blade.php, admin/layouts/app.blade.php,
    admin/settings/general.blade.php, admin/whmcs-import/mapper.blade.php.
  • resources/views/client/announcements/show.blade.php,
    client/auth/forgot-password.blade.php, client/auth/invite.blade.php,
    client/auth/login.blade.php, client/auth/register.blade.php,
    client/auth/reset-password.blade.php, client/auth/two-factor.blade.php,
    client/cart/configure.blade.php, client/kb/show.blade.php,
    client/layouts/app.blade.php,
    client/layouts/partials/language-selector.blade.php,
    client/unsubscribe.blade.php.
  • resources/views/legal/layout.blade.php, sections/topbar.blade.php,
    welcome.blade.php; themes/flavor/views/client/layouts/app.blade.php,
    themes/flavor/views/welcome.blade.php.

Also in 1.5.0: from 1.5.0-beta.1

Changed

  • The WHMCS import screens are redesigned. A header that says what the
    importer promises (read only, preview before importing, every record
    logged) and the three steps; the connection form in groups and saved
    connections as cards; the import type as tabs; a count of the fields mapped;
    the preview, run and save buttons in a bar that stays in reach; the preview
    side by side; the log as coloured totals. Right to left and on phones, in
    every language.

For developers

  • The beta channel is covered end to end: tests for which channel offers
    which release, and an update lab scenario in which the stable channel does
    not see a beta, the beta channel updates to it, and then to the stable
    release made from the same commit.

Database changes

  • None.

For theme and module authors

  • Nothing changed for modules, themes or hooks.

Views a theme may override that changed

  • resources/views/admin/whmcs-import/index.blade.php,
    mapper.blade.php and log.blade.php; new: _styles.blade.php and
    _steps.blade.php in the same folder.

The full history is in CHANGELOG.md. The package below is signed; the updater checks the signature before it uses it.