Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 01/28/25 in all areas

  1. While I understand that bugs are part of any Release Candidate cycle, it's concerning that we are still discussing basic optimization issues like proper OPcache support. And let's not even get started on the fact that we still don't have 100% native Nginx support. This becomes particularly ironic with the introduction of the new WHMCS Cloud Solution. With cloud hosting, the resource costs are on their side, so you'd think they'd be rushing to support Nginx to reduce their own infrastructure expenses. It's like being sold a high-performance engine but being told you have to power it with hamster wheels. Maybe once their bills start rolling in, Nginx support will suddenly become a priority. This all points to the bigger issue: the development velocity. Core development feels like it's just about "keeping the lights on" (PHP/ionCube updates) rather than actual innovation. This stagnation has allowed third-party developers like ModulesGarden to build entire businesses by selling us functionality that should have been in the core a decade ago. When you look at the "Total Cost of Ownership" license fees + necessary third-party modules, the value proposition is slipping. Newer platforms like Upmind are entering the market with an API-first architecture and modern features built-in from day one. If WHMCS continues to outsource innovation to the community while raising prices for maintenance updates, that competitive threat is going to become an exodus very quickly. We need core features that match the modern hosting landscape, not just compatibility patches.
    4 points
  2. Hi WHMCS ecosystem developers! I am excited to share an early heads-up about the upcoming WHMCS 9.0 release by the end of 2025 - a major update that brings important changes to the platform’s technical requirements. As part of this release, several core dependencies will be updated, and minimum system requirements will be increased. These changes are designed to improve performance, security, and compatibility with modern PHP standards. Key Updates in WHMCS 9.0: Minimum PHP version: 8.2 Recommended PHP version: 8.3 Minimum ionCube Loader version: 13.0.2 or higher Recommended ionCube Loader version: 14.4.0 or higher Updated dependencies: A number of underlying libraries and components have been upgraded. Some notable changes include: Smarty v3.1.48 —> v4.3.4 Legacy Smarty Tags are being deprecated and will no longer function in 9.0. Smarty Template Objects (including their use in plugins) will no longer be supported. guzzlehttp v7.4 —> v7.4.5 illuminate v7.x —> v9.0 I have attached a provisional list of dependency changes to this post. Please also use this thread to provide your feedback and ask questions of the Development Team regarding these requirement and dependency changes. These changes will require action from module developers to ensure continued compatibility. We recommend reviewing your module code and preparing for updates ahead of the release. We’ll be sharing more details, including a release window, definitive changelog and developer guidance, between now and the end of 2025 to help you get ready. Thank you for being a valued part of the WHMCS ecosystem. We appreciate your continued support and look forward to working together to make WHMCS 9.0 a successful release. whmcsv90_composerlock_provisional.txt
    3 points
  3. Okay, maybe I was too quick about credit notes. It seems a lot of the features are "coming soon™️". This is not a Release Candidate lol. This is not even alpha. This is internal development. Nothing can convince me that this release didn't just happen because WHMCS promised us a release in December.
    3 points
  4. Yeah, except for adding AI to domain search, this release doesn't really provide on any of the other promises. Credit notes doesn't work either. When you cancel an invoice, WHMCS just adds a transaction to the invoice. If the invoice has a total of $100, WHMCS just adds a transaction of $100 and cancels the invoice. There's no credit note or anything.
    2 points
  5. How WHMCS have set this as a RC instead of a Beta is insane. It's a huge upgrade in terms of it's impact on themes/modules. No beta, no reply from WHMCS, no forums specific to v9.
    2 points
  6. Your process sounds good apart from WHMCS. I would never recommend trying to import tables to new files. You need to update your existing install as normal. You can update from your version but you may have more luck doing a manual update. Backup everything, upload the new v8.13 files, adjust your hosting/server settings to meet the requirements (e.g you may need to update PHP) then run the installation script.
    2 points
  7. @BENELUX, Today's the day!! https://blog.whmcs.com/133775/whmcs-90-release-candidate-out-now
    2 points
  8. This week or next! It sure would be nice to double the size of the engineering team temporarily for one release every few years!
    2 points
  9. @stormy, I'm glad to hear the e-invoicing feature will be a real value add for you. We are working with expert solution-providers in this space, so we're confident about delivering an easy to use and compliant solution with the broadest coverage. @andp97, Yes, by the end of the year in a pre-release version of WHMCS you will have access to this new feature. This bullet point actually describes two significant features which we're very excited about: 1. A RESTful API which provides access to the product catalogue and shopping cart logic. This will provide a suite of new endpoints to get product catalogue information, add, manipulate and get information about items in the cart (including price breakdowns and totals) and much more, all without touching the cart.php file or PHP session data. This means that power users could create their own highly-bespoke frontends whilst WHMCS handles the maths in the background, before seamlessly passing visitors to the checkout page to complete payment. 2. A brand new thin client powered by the aforementioned new API capabilities, providing a thoroughly modern purchase experience based on Vue.js. I've attached a sneak peak below. The new BuyFlow is a compiled Single-page application, meaning the layout isn't manipulated through templates, but you will be able to customise the colours to match your theme through a custom.css overrides file. The shopping cart as it exists today (cart.php and order form templates) isn't going away and will still be available if you'd like to stay with the familiar experience. Stay tuned to our blog and socials over the coming weeks for more information!
    2 points
  10. Hi @venkat.j, The current latest version is 8.13. This behaviour suggests the dates were set to 00/00/0000, either by an admin (in which case there should be an entry in the client's Log tab) or by a rogue after-market module (in which case there probably wouldn't). You can edit the date fields to set the actual dates and click Save Changes. The correct dates will be stored.
    2 points
  11. Hi all, In 8.13 a small improvement was made to the accounting of refunded mass-pay invoices. Prior to this the totals of mass-pay invoices were included in the overall income statistics, but now they are excluded as it's already accounted for by the original invoices.
    2 points
  12. But you did ask them, and not by just posting here? EDIT: This is a bit old now, but a fast search on this board found:
    2 points
  13. Hello @ThemeMetro This is a known issue, and we have published a HotFix. For more details, please review the following. Apologies for any inconvenience. Kind regards, Stephen.
    2 points
  14. Thanks to @Mytihost, I found an elegant solution for this issue. The following hook: add_hook('ClientAreaPage', 1, function($vars) { if (!empty($vars['clientsdetails']['customfields'])) { $customfieldsAssoc = []; foreach ($vars['clientsdetails']['customfields'] as $field) { $customfieldsAssoc[$field['id']] = $field['value']; } return ['customfieldsAssoc' => $customfieldsAssoc]; } }); makes available the value of any client custom field in a template, using i.e. the form {$customfieldsAssoc.17} (where "17" is the id field in the tbl customfields)
    2 points
  15. Hi @Jade D, I have responded to your ticket, but just wanted to follow up here so there's an answer if anybody else comes across this. The underlying issue here is that your web server was advertising a domain other than that registered for your license. This causes the license cache in your install to be invalid, and so your install needs to check in with our licensing infrastructure to validate your license. Since the details we held about your license were different to those being advertised by your web server, your install kept making a request to our licensing API. We rate limit all requests made to our licensing infrastructure to ensure stability thereof for all our customers. If your server sends too many requests, it will be temporarily blacklisted as part of this rate limit. To resolve this, make sure that your web server is only advertising the server_name that we have listed in your Valid Domains. Wait for 30 minutes or so and the rate limit will be removed, then your install will get a response back from the licensing servers that your license is valid and access will be restored. If anybody is unable to get to the bottom of this, please reach out to our support team and we can help!
    2 points
  16. You aren't authenticated in your hooks. The hooks aren't running as you - they're running as the system. WHMCS doesn't offer a native way of logging in as an admin in a hook. If you just want to download the invoice, you can include /includes/invoicefunctions.php and run the pdfInvoice($invoiceId) function.
    2 points
  17. Hello, Not at all and it's highly recommended, to change the admin path.
    2 points
  18. I am happy to say that the development cycle of vBLink 2.0 is now complete. The release was delayed for a complete ground-up rewrite after WHMCS 4 was announced. It is not ready for download just yet; I have not taken the time to create an installer or documentation because of two major issues that may become a factor in the long term success of vBLink. The first issue is vBulletin 4 support is not included. This is in part because of the fact that I do not agree with decision by vBulletin to change the licensing structure essentially us to purchase new licenses. I own three licenses, two for production sites, one for a development site. The cost to upgrade is going to be huge, especially if I choose the publishing suite. So at this point I have no access to vB4 code. The second issue is that from a business standpoint vBLink has not been a success, or at least the free/paid model that it has been distributed with. In the past year there have been over 400 downloads of vBLink but less than 2% were paid licenses making vB4 support hardly justifiable. So the question now is what to do next, and that is the reason that I am posting this message. Obviously, vBLink without vB4 support is only going to be useful for a short time until v4 goes gold. But without a solid community and financial backing behind it, I have no reason to continue development. But one promise I will make is that if I do walk away from vBLink, I will release all source code into the public domain; I do not believe in holding code hostage. If I do in fact release vBLink 2.0, I'm thinking of a 3-tier release structure... vBLink Basic (Free, Fully Encoded with only account bridging and no extras) vBLink Pro (Mid-range cost, a few admin module source files encoded, fully functional) vBLink Pro Dev (Highest cost, fully functional with full source) All feedback is welcome and will help determine the future of this vBulletin integration.
    2 points
  19. Thanks for the detailed update! It’s great to see that ModulesGarden is moving quickly with WHMCS 9.0 compatibility, especially for modules like cPanel Extended and Proxmox VE. I’m curious have you noticed any specific issues or challenges when integrating custom-developed WHMCS modules with the new version, particularly around the updated checkout experience or recurring payments? It would be helpful to know what to watch out for before upgrading.
    1 point
  20. I’m honestly not convinced by these repeated price increases, especially when they happen without clear prior notice. I’m a small provider managing around 10–20 clients only, and with the latest increase, the subscription is becoming financially unjustifiable. At this scale, the cost is no longer proportional to the value received and is starting to feel more like a burden than a business tool. I understand that businesses evolve, but constant yearly increases without meaningful added value for small users come across as exploitation rather than progress. If this pricing strategy continues, I’m seriously considering moving away from the entire WebPros ecosystem, including WHM and WHMCS. At the very least, there should be better transparency, advance notifications, and fair pricing options for low-usage customers.
    1 point
  21. What I find somehow strange after being using WHMCS for 20 years.. when there was only 2-3 people in the company... bugs was fixed quickly often the same day. Now that I have a list of bugs reported many of them with 1 min solutions to implement, and they still doesnt get implement in X versions of whmcs 8x and still not fixed in WHMCS 9. So I dont know if being a large owned company is always a good thing. Just in December alone me and other people I work with found 3 new bugs of things that has been working since whmcs 5 and suddenly not working and per documentation should work.. I am actually concerned that the developing department / team doesnt have good working structure as they introduce bugs that should not be there that has been working for years. This make us need to use more time on testing before each upgrade and time testing is also a huge cost.. whmcs. should going forward be better in quality and also fixe the backlogs of bugs.
    1 point
  22. I must have something set up incorrectly because the Login to DirectAdmin button doesn't work if the passwords don't match. If the client changes their password on DirectAdmin then the button only directs them to the login screen on the DirectAdmin server.
    1 point
  23. ETA: Estimated Time of Arrival. By definition, not exact. 😉
    1 point
  24. @RadWebHosting's recommendation here is brilliant, and would be my suggestion too! Of course, you can also see a list of all overdue invoices at Billing > Invoices > Overdue in the Admin Area. If you'd be interested in a new event being added to your Notifications settings for when an invoice becomes overdue, I'd recommend opening a feature request here: https://requests.whmcs.com./ I can absolutely see how this would be useful, so getting that feature request open will allow others to comment on and vote for your request. Hope this helps :-)
    1 point
  25. Feel free to contact us for support: https://radwebhosting.com/support
    1 point
  26. Una buona notizia e' che il nostro team di sviluppatori sta attivamente lavorando per aggiungere la gestione di fatture elettroniche in una delle prossime release di WHMCS. In attesa di avere piu' dettagli nei prossimi mesi, non si hanno ancora tempistiche o specifiche. Certo e' che si potranno emettere fatture elettroniche in diversi formati, incluso Fattura PA. Per rimanere aggiornati potete sottoscrivere alla feature request corrispondente: https://requests.whmcs.com/idea/add-electronic-invoicing
    1 point
  27. can you maybe release an update to 8.13 to add a tool similar to the PHP compatibility tool that shows what files use these old components and won't be compatible? it'll help hosts like us that rely in multiple vendors plugins understand who we need to reach out too to ensure they're getting WHMCS v9 ready.
    1 point
  28. You should write your own. AI is not to be trusted.
    1 point
  29. 1 point
  30. Hi @File_Explorer @TheHostingHeroes, Some users have reported poor performance of this query is resolved by updating their MySQL server version. So please try that first. As a workaround you can remove the /modules/widgets/Billing.php file.
    1 point
  31. Hello, Here, I am sharing some steps that you need to follow to fix the issue - 1. Verify the File: Check if the captcha.tpl file is present in the templates/default/includes/ directory of your WHMCS installation using FTP or your hosting control panel. 2. Restore or Upload: If the file is missing, restore it from a backup or upload a fresh copy from another WHMCS installation that includes it. 3. Check Theme Compatibility: After upgrading WHMCS or changing your theme, the new theme may lack the file. Revert to a previous theme or choose one that includes the necessary functionality. If you're using a custom theme, you may need to create the missing captcha.tpl file or choose a theme that includes the required functionality. Thanks
    1 point
  32. We're pleased to announce the release of WHMCS 8.13 Release Candidate. This marks the end of feature development for the 8.13 series and is the final stage before version 8.13 is promoted to General Availability status. WHMCS 8.13 includes the following new functionality and enhancements: Manual User Password ResetsOne of our most requested admin features is here. With over 250 community upvotes, WHMCS 8.13 introduces the ability to reset a user's password directly from the Admin Area. This...View the full blog post
    1 point
  33. Yes. That's exactly what the Scheduled Ticket Replies and Notes feature does. Please test out the feature and share your feedback on your experience with it here.
    1 point
  34. Technically the other way round - opensrs bought enom and that’s when enom fell apart
    1 point
  35. Loads fine in Firefox, but Vivaldi (and a few others) sees what he does. Related to a javascript that's loading. It's a webpros script.
    1 point
  36. Hi @elonmusk, The LocalAPI user is invoked locally. Ie. By a file on your website that isn't a part of the stock WHMCS software. This will likely be an after-market customisation, perhaps something like a custom order form. I suggest comparing your WHMCS files against the stock ones for any additionals you may have, as they could be the cause.
    1 point
  37. Oh boy, didn't even read this until I posted. Negative -$1 deactivates the option. I'll show myself out!
    1 point
  38. I’ve had a similar issue before, and it turned out to be a syncing problem between WHMCS and Stripe. It seemed like WHMCS didn’t update its records properly after processing a payment, but Stripe ended up charging clients twice. In my case, it was due to a misconfigured webhook or an automated retry that triggered the second charge. It’s definitely worth checking your payment gateway settings and logs, and if it keeps happening, you might want to contact WHMCS and Stripe support to get to the bottom of it.
    1 point
  39. I Need to.. any whmcs developer ? Thank you
    1 point
  40. Lagom WHMCS Client Theme has been updated to 2.0 version! Order Now Changelog Documentation Services Contact Different Styles & Colors Lagom WHMCS Client Area Theme consists of 4 unique styles. There are 5 different color schemes available for each style. Modern Futuristic Default Depth Style Manager Provides essential tools used to manage Lagom theme colors and styles without having any technical know-how. You will be empowered to apply various Styles and Color Schemes to tailor our theme to your brand style. Learn More Menu Manager From now on, you do not need to create complicated WHMCS hooks to modify the Lagom theme navigation. Menu Manager delivers a super convenient option to set up the menu items from the WHMCS addon. Learn More Multiple Layouts Make full use of 5 unique layouts for the main menu navigation and 2 various layouts for the footer. Other Lagom Features Login Based Layouts Display different menu and footer layouts based on the customer's login status. Learn More Basic SEO Management Manage SEO for selected theme pages. Assign your custom page title, description, and social image. Learn More Custom Layout for Pages Assign a unique Lagom Layout to specific pages and overwrite settings made in Layout Manager. Learn More Affix Theme Navigation Affix the top Lagom theme navigation when a customer scrolls your website up. Learn More Multiple Element Styles Using a few simple clicks you can choose from 3 different styles available for particular Lagom elements. Learn More Multiple Page Templates Define various templates for selected Lagom theme pages and configure its settings. Learn More Different Fonts Change Font Family used in the Lagom theme with a few simple clicks. Learn More Affix Theme Sidebars Affix theme sidebars to the top of the browser window. Learn More Hide Sidebars Hide Lagom theme sidebars for selected pages in Page Manager. Learn More
    1 point
  41. WHMCS users and client accounts have separate contact information and they require separate updates to change details like the email addresses. The user management system allows a single user to access multiple client accounts. This separates authentication and authorization from services, billing, and support. To learn how to change the client account and the user account email address so they match please review this help guide: https://help.whmcs.com/m/managing/l/1681243-updating-user-and-client-account-details With this hook added to your WHMCS installation the system will now "Sync" the Client Account Email Address to match the User Account Email Address only when the change is made under the Account Details page via the client area. This hook adds a little "Note" under the Email Address field under the Hello Client! > Account Details section of the client area to inform that when this Email Address is changed, they will be logged out and they will need to log back in using the new Email Address they just set since this hook is updating both the client account and user account email addresses. Here is an example of the Account Details page Email Address field with this note: Via the Admin Area, when a client does this change and the hook was used it will make a log entry just like this: This entry indicates that the Client/User Email Sync Script hook was a success. Now both the Client Account Email Address and the User Account Email Address match for that client account. If there are multiple Users associated with the Client Account, this will only change the Email Address of the Owner of the account. <?php /* This script will update both the Client Account Profile email address and the user account email address when the change is made to the Account Details page for the email address field. Otherwise, you would have to update the email in both places and follow this article: https://help.whmcs.com/m/managing/l/1681243-updating-user-and-client-account-details Upload this file to your /includes/hooks directory of your WHMCS installation. There will be a Log entry when this script runs. @WHMCSDanny */ add_hook('ClientAreaHeadOutput', 1, function($vars) { // Only run if the on the Account Details page via the client area. // The action is going to be "details". This will make sure this message does not show anywhere else. $action = $_GET['action']; if($action == "details") { //Input the message under the Email Address field that they will be logged out after making the change. return <<<HTML <script type="text/javascript"> $(document).ready(function() { jQuery("input[name='email']").after('<span style="color:red; font-size:9pt;"><b>Note:</b> Changing your email address here will sync the email with your User Account. You will be logged out after you change the email. You must login using the new email address you just set.</span>'); }); </script> HTML; }; }); // prevent file from being loaded directly if (!defined("WHMCS")) { die("This file cannot be accessed directly."); } else { function clientowneruseremailsync_changeUserEmail(int $client_id, string $client_email){ // call the API and grab the owner user ID $command = 'GetClientsDetails'; $postData = array( 'clientid' => $client_id, 'stats' => false, ); $results = localAPI($command, $postData); if ($results['result'] == 'success') { // success! $client_owner_user_id = $results['client']['owner_user_id']; if (is_numeric($client_owner_user_id)){ // got a number, so it should be a valid owner user ID // now to perform the update to the user account to match the email set for the client account $command = 'UpdateUser'; $postData = array( 'user_id' => $client_owner_user_id, 'email' => $client_email, ); $results = localAPI($command, $postData); if ($results['result'] == 'success') { logActivity("Client/User Email Sync Script - Emails Successfully Changed and Synced. The e-mail address is set to $client_email for the Client Account and the Owners User ID: $client_owner_user_id", $client_id); } else { logActivity("Client/User Email Sync Script - Failed to change the e-mail address to $client_email for the Owners User ID: $client_owner_user_id . Results: ". $results, $client_id); } } } else { logActivity("Client/User Email Sync Script - Failed to verify that an e-mail change occurred on the clients profile. Results: ". $results, $client_id); } } add_hook('ClientEdit', 1, function($vars) { // Only run if the clients account profile email address is being changed. if ($vars['email'] != $vars['olddata']['email']){ // email is being changed. Update owning user accordingly. // get the client ID. It should be $vars['userid'] $client_id = $vars['userid']; // get the new e-mail address $client_email = $vars['email']; // call our helper function clientowneruseremailsync_changeUserEmail($client_id, $client_email); } }); } ?> Enhanced Version - Added a checkbox and tooltip In this new updated version of this hook, I added a checkbox/tooltip for the end-users to decide if they want to use this option to sync the Email Address under the Profile page too. Otherwise, nothing happens and WHMCS works as normal. The checkbox needs to be checked before it will run the same hook code to update both email addresses in both locations. (Account Details and Profile sections via the client area) <?php /* This hook script will update both the Client Account Profile email address and the User Account email address When the change is made to the Account Details page for the email address field only. It does not work for the Profile page. This version adds a new checkbox with a tooltip to let the end-user decide if they want to use this option or not. The checkbox needs to be checked for the hook to execute. If the checkbox does not get checked WHMCS works as expected and updates just the Account email. The Profile email account will still need to be updated if they want it to be the same. Otherwise, you would have to update the email in both places and follow this article: https://help.whmcs.com/m/managing/l/1681243-updating-user-and-client-account-details Upload this file to your /includes/hooks directory of your WHMCS installation. There will be a Log entry in the admin area when this script executes. @WHMCSDanny */ add_hook('ClientAreaHeadOutput', 1, function($vars) { // Only run if the on the Account Details page via the client area. // The page action is "details". This will make sure this message does not show anywhere else. $action = $_GET['action']; if($action == "details") { //Input the checkbox and tooltip under the Email Address field return <<<HTML <script type="text/javascript"> $(document).ready(function() { jQuery("input[name='email']").after('<input type="checkbox" name="syncEmails" id="syncEmails"> <span style="color:red; font-size:9pt;"><b>Sync Email with your User Account Email</b></span><span class="form-group"> &nbsp; <i class="far fa-question-circle" data-toggle="tooltip" data-placement="top" title="This option will sync your Email Address Here with your Profile Email Address. You will be logged out and will need to login with your new email address. If you do not check this option you will need to update it under the Your Profile page as well"></i></span>'); }); </script> HTML; }; }); // Prevent file from being loaded directly if (!defined("WHMCS")) { die("This file cannot be accessed directly."); } else { if (isset($_POST['syncEmails'])) { // Checkbox is checked // Perform actions and the logic to check the emails and replace them with the new one function clientowneruseremailsync_changeUserEmail(int $client_id, string $client_email){ // call the API and grab the owner user ID $command = 'GetClientsDetails'; $postData = array( 'clientid' => $client_id, 'stats' => false, ); $results = localAPI($command, $postData); if ($results['result'] == 'success') { // Success we have the owners user ID from the database! $client_owner_user_id = $results['client']['owner_user_id']; if (is_numeric($client_owner_user_id)){ // We have the ID number, so it should be a valid owner user ID // Perform the update to the user account to match the email set for the client account $command = 'UpdateUser'; $postData = array( 'user_id' => $client_owner_user_id, 'email' => $client_email, ); $results = localAPI($command, $postData); if ($results['result'] == 'success') { logActivity("Client/User Email Sync Script - Emails Successfully Changed and Synced. The e-mail address is set to $client_email for the Client Account and the Owners User ID: $client_owner_user_id", $client_id); } else { logActivity("Client/User Email Sync Script - Failed to change the e-mail address to $client_email for the Owners User ID: $client_owner_user_id . Results: ". $results, $client_id); } } } else { logActivity("Client/User Email Sync Script - Failed to verify that an e-mail change occurred on the clients profile. Results: ". $results, $client_id); } } add_hook('ClientEdit', 1, function($vars) { // Only run if the clients account detaoils email address field is being changed. if ($vars['email'] != $vars['olddata']['email']){ // Wmail is being changed. // Get the client ID. It should be $vars['userid'] $client_id = $vars['userid']; // Get the new e-mail address $client_email = $vars['email']; // Call the helper function to make the change clientowneruseremailsync_changeUserEmail($client_id, $client_email); } }); } } ?> At the time of writing this post, this process was tested on the latest stable release of WHMCS 8.9.0 I hope you find this useful. If you have any feedback or questions, please feel free to reply to this thread! WHMCSDanny
    1 point
  42. For many businesses, there will be keywords that you do not want customers to be able to use. For example, you might want to prevent them from being able to create services under any of your domain names, or prevent the use of strings like "admin" or "root" in the "First Name" and "Last Name" fields. By making use of action hooks, it is totally possible to add this functionality. In this post, I'll show you how to get this setup, and how you can add your own rules. Overview To make this work, we're going to be making use of Action Hooks - specifically, the ShoppingCartValidateCheckout hook. If you've never used hooks before, I'd recommend reading our Getting Started guide, which will help you to understand the basics of what we'll be doing here. Step 1: Set up your hook file To begin, open your WHMCS instance's filesystem, and navigate to /path/to/whmcs/includes/hooks and create a new file keyword_filter.php. Now open the file, and paste in the following: <?php add_hook('ShoppingCartValidateCheckout', 1, function($vars) { // Content goes here }); This will tell WHMCS that we are using the ShoppingCartValidateCheckout hook, and will allow us to retrieve the variables provided to us. As this article goes on, we'll be adding to this base layer until we have our finished, fully-functional script. Step 2: Define your keyword filters There are many different ways that we could define what strings are banned in which fields. For maximum legibility and modularity, I've decided to use a map. This will allow us to associate one set of data (the "key"), in this case the field name(s) to apply the filter to, and another (the "value"), which in our case is a list of banned keywords. Here's the code: <?php add_hook('ShoppingCartValidateCheckout', 1, function($vars) { $fieldKeywordMap = [ [ // The 'firstname' and 'lastname' fields cannot contain the strings // "admin", "root" or "superuser". 'fields' => ["firstname", "lastname"], 'keywords' => ["admin", "root", "superuser"] ], [ // The 'email' field cannot contain the strings "@whmcs.com" or // "@google.com". 'fields' => ["email"], 'keywords' => ["@whmcs.com", "@google.com"] ], // Add more mappings as needed ]; }); Each set of 'fields' and 'keywords' is a mapping. You can add as many of these as you need. We'll be returning an error based on whether or not the field contains these keywords (i.e. if they are substrings). For example, if the user enters "admin123" for their firstname and "john.smith@google.com" for their e-mail, both of these filters will apply because the substrings "admin" and "@google.com" are present within the 'firstname' and 'email' fields respectively. You can find a full list of available fields in the documentation for this hook. Step 3: Implement logic to check field submissions for any banned substrings Now that we've defined our 'filters', we need to implement the logic that's going to make them work. Here's the full script, explained in the provided comments: <?php add_hook('ShoppingCartValidateCheckout', 1, function($vars) { $fieldKeywordMap = [ [ // The 'firstname' and 'lastname' fields cannot contain the strings // "admin", "root" or "superuser". 'fields' => ["firstname", "lastname"], 'keywords' => ["admin", "root", "superuser"] ], [ // The 'email' field cannot contain the strings "@whmcs.com" or // "@google.com". 'fields' => ["email"], 'keywords' => ["@whmcs.com", "@google.com"] ], // Add more mappings as needed. ]; // Initialise array to store error messages. $errors = []; // Iterate through all of your mappings. foreach ($fieldKeywordMap as $mapping) { // Get the 'fields' and 'keywords' separately for each mapping. $fields = $mapping['fields']; $keywords = $mapping['keywords']; foreach ($fields as $fieldName) { // Retrieve the value for the field from $vars[] provided by the hook. $fieldValue = $vars[$fieldName] ?? ''; // Check if the field is empty - if it is, skip the checks. if (!$fieldValue) continue; // Check if any of the keywords are a substring of the field value. foreach ($keywords as $keyword) { if (stripos($fieldValue, $keyword) !== false) ) { // If there is a match, add it to the list $errors[] = "'$fieldName' cannot contain '$keyword'. Please remove this and try again."; } } } } // If any errors are present, return them - otherwise, return true. return $errors ?: true; }); Here's a little summary of how it works: Iterate through all of your mappings ('filters') Check all fields for each filter If the field value is blank, skip all checks for that field - we need to do this since this field is only included for new users If the field value is not blank, carry on to checks Check if any keywords are a substring of the field value If they are, add that infraction to an array of errors to be returned If not, do nothing If there are any errors, return them. If all checks are passed and no keywords are present, return true. The only part of this code that you should need to modify is the top section, where you define your filters. If any of the filters are matched, here's what'll be displayed in WHMCS: Step 4: Prettify error messages (optional, but recommended) As it stands, our hook is completely functional. If any banned words are present, an error will be returned. However, our script looks like a customisation, and you'll probably want to make it appear like native functionality. The issues are: We're currently using the $fieldName, which doesn't read like English Language used doesn't fit in with the rest of WHMCS's error messages To second issue is fixed by adjusting the error message, so that's easy! To fix the first problem, we'll use another map to correlate each $fieldName with its "English equivalent" (which I've just called $friendlyFieldName: <?php add_hook('ShoppingCartValidateCheckout', 1, function($vars) { $fieldKeywordMap = [ [ // The 'firstname' and 'lastname' fields cannot contain the strings // "admin", "root" or "superuser". 'fields' => ["firstname", "lastname"], 'keywords' => ["admin", "root", "superuser"] ], [ // The 'email' field cannot contain the strings "@whmcs.com" or // "@google.com". 'fields' => ["email"], 'keywords' => ["@whmcs.com", "@google.com"] ], // Add more mappings as needed. ]; // Map field names that you're using above to their "English equivalent". $friendlyFieldNames = [ 'firstname' => 'First Name', 'lastname' => 'Last Name', 'email' => 'Email Address', // Add more field name translations as needed. ]; // Initialise array to store error messages. $errors = []; // Iterate through all of your mappings. foreach ($fieldKeywordMap as $mapping) { // Get the 'fields' and 'keywords' separately for each mapping. $fields = $mapping['fields']; $keywords = $mapping['keywords']; foreach ($fields as $fieldName) { // Retrieve the value for the field from $vars[] provided by the hook. $fieldValue = $vars[$fieldName] ?? ''; // Check if the field is empty - if it is, skip the checks. if (!$fieldValue) continue; // Check if any of the keywords are a substring of the field value. foreach ($keywords as $keyword) { if (stripos($fieldValue, $keyword) !== false) { // Translate the field name to a nicer name for the error message. $friendlyFieldName = $friendlyFieldName[$fieldName] ?? $fieldName; // Add it to the list $errors[] = "$friendlyFieldName cannot contain '$keyword'"; } } } } // If any errors are present, return them - otherwise, return true. return $errors ?: true; }); Simply add a new mapping for each $fieldName that you use in the $friendlyFieldNames array, and they'll read well and feel like a native part of WHMCS: And there we have it: a hook script that can be easily extended to include as many fields and keywords as you require, and it feels totally native too! Customising/extending this script Feel free to customise this script to you heart's content, whether you want to change how it behaves or extend its functionality. However, please keep in mind that our Technical Support team won't be able to help you troubleshoot any problems that you may encounter should you make any changes. Use at your own risk. Suggestions for other "Tips & Tricks' articles If you'd like to see an example of how we can customise WHMCS in other ways, please do give us your suggestions!
    1 point
  43. Hello, The tbllog_register table holds data on the actions taken by the daily cron tasks which are available in the admin area at Utilities > Automation Status. It is where the results of a cron task are stored. The daily cron email report aggregates its content from these rows. These are the actions taken by the daily cron tasks which are available in the admin area at Utilities > Automation Status. At present it is not possible to prune this log from within WHMCS. If you'd like to see this included I'd encourage you to add your vote or comments to https://requests.whmcs.com/idea/cleanup-tool-to-prune-tbllog_register-table Ideas with the most votes and activities are reviewed by our team. As of WHMCS 8.1 and above we have optimized the indexing for cron log data. https://docs.whmcs.com/Changelog:WHMCS_V8.1 CORE-14970 - Optimize indexing for cron log data In the meantime, if this is something that you would like to work with, you can do so with a SQL query. For example, the SQL query below will remove any entries in that table that predate 2023. You can modify this to suit your requirements. DELETE FROM `tbllog_register` WHERE created_at < "2023-01-01"; As always, please ensure you back up your database before performing any such direct actions on the WHMCS database.
    1 point
  44. YOU CAN USE MY EMAIL DESIGN FOR YOUR COMPANY, THANKS TO THIS COMMUNITY I HAVE FOUND A LOT OF COMMUNITY CONTENT, SO I GIVE YOU MY PERMISSION TO USE IT. Post Update: After a long time working on the code, I have managed to get it to look correct. There were many problems that I am going to name now, which I fixed to make it display correctly; Global Email CSS Styling: Some generic tags will not work, for example 'body', instead of adding it to Global Email CSS Styling, I added it directly to the HTML code to make it work. Error ❌ body{font-size: 17px; line-height: 25px; color: #f1f1f1; font-family: 'Open Sans', sans-serif; font-weight: 400; margin: 0px; background-color: #070B41;} Solution ✅ <body style="font-size: 17px; line-height: 25px; color: #f1f1f1; font-family: 'Open Sans', sans-serif; font-weight: 400; margin: 0px; background-color: #070B41;"> Sometimes you have to add an '!important' to the CSS code, because another tag is replacing it. For example, I wanted to put links with a different color and no style; Error ❌ a{text-decoration: none; color: #1094F0;} Solution ✅ a{text-decoration: none!important; color: #1094F0!important;} Some images on some providers do not load correctly because it can detect that the domain is not secure. For example; Error ❌ https://universalgg.com/assets/img/mails/logo.svg Solution ✅ https://i.imgur.com/7nQbkxQ.png It has taken me a long time to investigate, since on localhost it was working correctly. I have tried various SMTP providers and it was working fine too. Conclusion: The error is from WHMCS and not from my design, but it can be solved. All code: <!DOCTYPE html> <html> <head> <title></title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <style> .main-table{background-color: rgb(3 5 33 / 87%); border-radius: 20px; overflow: hidden; margin-top: 20px;} .content-table{padding: 50px 40px 50px 65px;} .h1-table{padding-bottom: 25px; font-size: 22px; font-weight: 700; color: #fff;} .btmspace-table{padding-bottom: 30px;}.top-line{padding-top: 30px;} .grey-line{border-top: 1px solid #707070;} .welcome-img{width: 50%; background-image: url('https://universalgg.com/assets/img/mails/img.webp'); background-position: left; background-size: cover; background-repeat: no-repeat;} .welcome-copyright{color: #DDDDDD; font-size: 12px; text-align: center;} a{text-decoration: none!important; color: #1094F0!important;} </style> </head> <body style="font-size: 17px; line-height: 25px; color: #f1f1f1; font-family: 'Open Sans', sans-serif; font-weight: 400; margin: 0px; background-color: #070B41;"> <table width="1140" border="0" align="center" cellpadding="0" cellspacing="0" class="main-table"> <tr> <td> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" class="content-table"> <tbody> <tr> <td colspan="2" style="padding-bottom: 35px;"> <img src="https://universalgg.com/assets/img/mails/logo.svg" style="max-width: 430px;" width="100%" height="auto" alt="logo"> </td> </tr> <tr> <td colspan="2" class="h1-table"> ¡Bienvenido! </td> </tr> <tr> <td colspan="2" class="btmspace-table"> Hola {$user_first_name}, revisa este correo electrónico en su totalidad, ya que contiene información importante. </td> </tr> <tr> <td colspan="2" class="btmspace-table"> Has registrado tu cuenta el día {$user_signup_date}. Necesitarás tu dirección de correo electrónico y la contraseña que elegiste durante el registro, para iniciar sesión.</br> Si creó la cuenta como parte de la realización de un nuevo pedido con nosotros, en breve recibirás un correo electrónico de confirmación del pedido. </td> </tr> <tr> <td colspan="2"> Por favor, no responda a este mail, es un mensaje automático. Le enviamos un cordial saludo, gracias por confiar en nosotros. </td> </tr> </tbody> </table> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" class="top-line"> <tbody> <tr> <td class="grey-line"></td> </tr> </tbody> </table> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" style="padding: 30px 40px 30px 65px;"> <tbody> <tr style="vertical-align: middle;"> <td style="padding-bottom: 20px; font-size: 15px; font-weight: 500; color: #1094F0;"> <a href="https://universalgg.com">Sitio web</a>&nbsp; | &nbsp; <a href="{$whmcs_url}">Área de clientes</a>&nbsp; | &nbsp; <a href="mailto:info@universalgg.com">Contactar</a> </td> <td style="padding-bottom: 13px; text-align: right;"> <a href="https://twitter.com/UniversalGamg"><img src="https://universalgg.com/assets/img/mails/s_twitter.svg" style="display: inline-block; margin-right: 15px;" alt="icon"></a> <a href="https://www.instagram.com/universal_gg/"><img src="https://universalgg.com/assets/img/mails/s_instagram.svg" style="display: inline-block; margin-right: 15px;" alt="icon"></a> <a href="https://discord.gg/nMxTQ5UZpM"><img src="https://universalgg.com/assets/img/mails/s_discord.svg" style="display: inline-block; margin-bottom: -1.5px;" alt="icon"></a> </td> </tr> <tr> <td colspan="2" class="welcome-copyright"> 2018-2023 &#169; {$company_name} </td> </tr> </tbody> </table> </td> <td class="welcome-img"></td> </tr> </table> </body> </html>
    1 point
  45. Apologies for bringing an old thread back from the dead but this issue has reared its ugly head again in version 8.13. We had an issue with a smarty variable in a custom template file triggering a security policy error so WHMCS Support suggested adding this security policy to our config file: // Smarty enable special variables policy: $smarty_security_policy = array( 'system' => array( 'enabled_special_smarty_vars' => array( 'session', 'foreach', 'section', 'block', 'capture', 'now', 'get', 'post', 'server', 'request', 'template', 'const', 'strstr', ), ), ); This fixed the issue with the template not working but now we are getting a "'strstr' not allowed by security setting" error when trying to send any email that contains this: {if strstr($client_credit, "GBP")}Blah blah blah{/if} The original security policy we had in place to allow "strstr" is still there but doesn't work if we also have the new "'system'" security policy in place, it works fine if we remove this leaving just the original security policy but ideally we need both the custom template and the code in the email to work! FYI our full security policy is listed here: // Smarty custom email based template policy: $smarty_security_policy = array( 'mail' => array( 'php_functions' => array( 'strstr', ), ), ); // Smarty enable special variables policy: $smarty_security_policy = array( 'system' => array( 'enabled_special_smarty_vars' => array( 'session', 'foreach', 'section', 'block', 'capture', 'now', 'get', 'post', 'server', 'request', 'template', 'const', 'strstr', ), ), ); Any ideas how to fix or if not, is there another workaround we could use to display conditional data depending on the currency used by the client?
    1 point
  46. @WGS It seems you moved from copying contents to paying money trying to hurt our website with negative SEO. Nicely done 👍 I've got two words for you: Stop wasting money. It doesn't work as I know how to deal with negative SEO Do you want me to post details? 😛
    1 point
  47. I personally think post count is enough of a "ranking" system. As for people that are employed, by WHMCS, well.. they just need something to indicate that (as they already do). I give little attention to a rank under a persons name. I give plenty of attention to their meaningful posts. To be blunt, "we" (whoever you may choose to put into that group) help WHMCS a lot more than I think they realize. Reward "us" with better support, or tangible things other than a fancy tagline and you might just be on to something when it comes to encouraging contributions. PS If you want to learn about how to engage people, you'll find much material on the subject online, including plenty of contradictions. I have quite a lot of experience managing a community many times larger than this, but it's a Open Source community.. and the reasons people are there are vastly different from the reasons they are here.
    1 point
  48. it's only taken you a couple of years to get to this stage of changing the ranks... it's one hell of a long journey if it's only just beginning now. or perhaps a more constructive approach would have been to discuss it first before implementing it?? 🙄 if I believe users think ranks are unimportant, then why should I give you suggestions for alternatives when they don't matter ??? I even lost my sarcastic "Legendary Member" tag for 90 days ROFL. 🤣 you want a suggestion Chris - to a user, is my rank, "Senior/Legendary Member" or "Honorary Contributor" ?? Is Kian a "Senior Member" or a "GearHead" ?? a casual user is not going to know which is the rank - nor will they care. i'd argue an Advisor should outrank a Contributor, but as I said, they're all meaningless... I told you years ago that you don't need to have both visible, there's an argument you don't need either. excellent - as a matter of regular routine, I have a screenshot of the entire original thread - I find that it's always good to keep a complete unadulterated record of these things for later use - consequences of actions can, and will, work in both directions. #KTTK 😉 absolutely correct - ideally, you engage with them before making decisions.... if ranks matter, they will speak up - if they don't, then that proves my point. as a demonstration of that Chris, when you start other community suggestion threads - how much response do they get?? exactly! nobody is interested - there's YOUR community Chris. users come here for one of two reasons - either they have a technical problem and they want an answer, or they're a developer and only interested in checking for new threads in SO&R, or posting about their latest addon... neither group are going to be interested in the minutiae of these forums, e.g ranks, tags etc. you might want to check mine too - i've gone from 6% to 95% used.
    1 point
  49. the easiest way would be a css entry in templates/six (or custom)/css/custom.css #order-premium_comparison .price-table-container .price-table { width: 250px !important; min-width: 250px !important; } if you wanted 5 columns, you'd change them both to 190px or less..
    1 point
  50. which is the definition of a lookup provider. all i'm saying is that WHMCS 7 is designed to either use whois, or a lookup provider, for ALL TLDs - you can't mix and match, e.g this module for .ge, but whois for .com - you have to put all your eggs in one basket.
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated