Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 12/06/2018 in all areas

  1. 7 points
    I believe (as software engineer I am). WHCMS should make this new SSL monitoring feature fully optional and allowing easy enable/disable settings in the configuration panel or in the configuration.php file in the simplest case. And that is because adding invasive new features must be done with quirurgical precision and always having in mind: maybe some customers does not want what we think they want. No mentioning that evidently the feature was not fully tested before released as stable. Recommending customer to edit files in your theme is not a smart move, since the new SSL monitoring bug is not only estetical problem, there are some backend processes involved... and also because mostly of your customers are not coders and expect a "working product". Next time guys you think in adding a new invasive feature, please consider giving us (your customers) the power to enable/disable as will any idea that maybe WHMCS think is good, but ends being a bad idea. I've been with WHMCS since almost 8 years ago.
  2. 5 points
    Some people want to show their client's credit balance when they login to client area, as the option not implemented by default in Six Template here is how to do it: 1) Upload the PHP file from Attachements to -> /WHMCS-Path/includes/hooks/ directory. WHMCS_SixTemplateCreditBalance.zip
  3. 5 points
    Hello Good People, Main site was built with WordPress, using a premium theme, with a heavy modification in design. WHMCS part was done using SIX as base, with mostly css modification, some html modification (mostly header and footer). Front end: https://dctit.host/ WHMCS: https://dctit.host/shop/ View Cart page: https://dctit.host/shop/cart.php?a=view Will appreciate your feedback. Kindly let me know your thoughts. Thanks.
  4. 3 points
    it looks like the SQL queries needed tweaking - i'll attach the updated file rather than posting the entire code, but basically i've just changed the three references of... tblpaymentgateways.* to... tblpaymentgateways.value .. and it's still on my list of things to do to update this widget properly for v7.7+ 📅 admin.php
  5. 3 points
    @WHMCS John your reply illustrates the biggest problem of WHMCS. You can't communicate. Not to your customers and not to each other. There hasn't been a single request on requests.whmcs.com asking for this feature, yet it is implemented. This has obviously been fuelled by your MarketPlace partners, not by your customers. And to be fair I wouldn't mind if a feature is useful and works, but you have to be open about it. You're not. And if it breaks, step up and get it fixed. Stop hiding behind arguments that you're not a system administrator. This is a developer at fault, 100%. You're only telling part of the story. You're not helping, at all. I can understand why your customers are getting more and more frustrated. It checks for a 51 error; It tries to get the SSL details for which it needs CURLINFO_CERTINFO. Even if cURL is working on the CLI, your PHP implementation can still fail. But that's not all. If you have a version of cURL on your server that supports CURLINFO_CERTINFO the cron doesn't necessarily work, simply because WHMCS needs a different database collation; which isn't part of a database migration nor of your release notes or documented requirements. WHMCS has been informed about the CURLINFO_CERTINFO problem AND have been given a workaround by at least two of your customers. It has already been reported as a bug. The fact that you keep saying that the 51 error code is what WHMCS is looking for shows that you're not communicating with each other. If you would, the troubleshooting page would have been updated with both the CURLINFO_CERTINFO information and the changed collation requirements would have been communicated, too. Neither is the case. On to solving the actual problem for those who read this too. Copy the following into a PHP file on your server. <?php $domain = 'www.whmcs.com'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://' . $domain); curl_setopt($ch, CURLOPT_CERTINFO, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_VERBOSE, true); if(curl_exec($ch) === false){ echo 'Curl error: ' . curl_error($ch); } $certInfo = curl_getinfo($ch, CURLINFO_CERTINFO); print_r($certInfo); ?> If you open it in your browser. The first line should start with: Array ( [0] => Array ( [Subject] => CN = *.whmcs.com [Issuer] => C = US, O = DigiCert Inc, OU = www.digicert.com If it doesn't your version of cURL doesn't come with CURLINFO_CERTINFO. You either need to update cURL or speak to WHMCS to implement an alternative (and keep your fingers crossed). If you need to update cURL tread carefully. Don't use third party repositories, either speak to a sysadmin or to support of the control panel you're using. If it does, try to run the cron manually: php -q crons/cron.php do --SslSync -vvv Are you seeing errors? They will probably be something like: SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1' (SQL: select `userid`, `domain` from `tblhosting` left join `tblsslstatus` on concat("" COLLATE utf8_unicode_ci, tblhosting.domain) = `tblsslstatus`.`domain_name` where `domain` != and `tblsslstatus`.`id` is null limit 100) This is because WHMCS made a breaking change. The solution is to add the following to your configuration.php: $mysql_charset = 'utf8'; Be careful as this may break your currency character(s). Head over to Setup >> Payments >> Currencies and save each and every currency you use. Double check if everything works by looking at transactions, invoices. Don't forget the PDFs. Was this so hard to document, WHMCS? Stop hiding. Start listening.
  6. 3 points
    there will be at least two short-term ways to do it... edit the code in the above template. edit scripts.min.js (where there URL is defined). method 2 implies that you should be able to do it via a hook (which would be a better long-term solution), but i've not been able to get it working yet... besides, now that v7.7.1 is released, I suspect there won't be any more updates, apart from hotfixes, until May 2019 and so no harm in editing the template or js files. so if you want to edit the template... {if $service.sslStatus} {if $service.sslStatus->getClass() eq "ssl-state ssl-inactive"}<a href="cart.php?gid=11">{/if}<img src="{$service.sslStatus->getImagePath()}" data-toggle="tooltip" title="{$service.sslStatus->getTooltipContent()}" />{if $service.sslStatus->getClass() eq "ssl-state ssl-inactive"}</a>{/if} {elseif !$service.isActive} <img src="{$BASE_PATH_IMG}/ssl/ssl-inactive-domain.png" data-toggle="tooltip" title="{lang key='sslState.sslInactiveService'}"> {/if} alternatively, in scripts.js (not used by WHMCS), you can change... jQuery(document).on('click', '.ssl-state.ssl-inactive', function(e) { e.preventDefault(); window.location.href = WHMCS.utils.getRouteUrl('/ssl-purchase'); }); to... jQuery(document).on('click', '.ssl-state.ssl-inactive', function(e) { e.preventDefault(); var gidvalue="11"; window.location.href = "cart.php?gid=" + gidvalue; }); minify/compress it and save it as /templates/six/js/scripts.min.js - or if you're familiar with the minified files, you could edit scripts.min.js directly... either method should work, there is no need to do both! it's probably easier to use the template edit, but I posted the js solution because it was the first one that I wrote for this and it seems a shame to let it go to waste if others want to use or improve upon it (e.g the basis of a hook).
  7. 3 points
    typical - i'm here for 50 weeks of the year, and I miss out on a freebie when i'm away. 🎄 that said, is it a sign of the times that my first thought was to wonder whether the pen was permanently on, or if the user has the option to turn it on and off. 😜
  8. 3 points
    <?php # Remove Terminated Products From Services Array Hook # Written by brian! function clients_services_remove_terminated_hook($vars) { $services = $vars['services']; foreach($services as $key => $service) { if ($service['status'] == "Terminated") { unset($services[$key]); } } return array("services" => $services); } add_hook("ClientAreaPageProductsServices", 1, "clients_services_remove_terminated_hook"); ?> you might need another hook to remove the Terminated link from the sidebar if you're showing that sidebar on your site... or even simpler, you should be able to hide it using custom.css
  9. 3 points
    It's absolutely the worst solution. It's commonly used by a lot of small reseller, but it's a very bad idea. If your hosting server will go down, also your own site will be down. Even if it's a planned management. And all customers of yours suddenly will enter in panic mode: "My PRECIOUS site is down, my PRECIOUS email is down, and my hosting provider is LOST and UNRESPONSIVE!!!!!!!" No, definitely you need to keep your own site elsewhere. And your own email service too.
  10. 3 points
    In 2016 I have questioned the WHMCS team about this function, I found the reply:
  11. 2 points
    Don't know if this is the right category to post this in, but I thought I wanted to share this. It's a very small hook that cancels an invoice once the product gets terminated. //<?php use WHMCS\Database\Capsule; add_hook('PreModuleTerminate', 1, function($vars) { $invoiceid = Capsule::table('tblinvoiceitems') ->where('relid', '=', $vars['params']['serviceid']) ->orderBy('duedate', 'desc') ->first(); Capsule::table('tblinvoices') ->where('id', '=', $invoiceid->invoiceid) ->update(['Status' => 'Cancelled']); }); Any feedback is much appreciated.
  12. 2 points
    the idea for this widget was started in the feedback thread below, but rather than hijack that thread with this project, it was easier to start a new thread in Third Party Addons. this "Enhanced ToDo List" admin widget, expands on the default widget by showing client names (or Company Name), service details (name/domain) and domain names as mouseover tooltips (I could put them in the body, but then space might become an issue)... for those that want to use this widget, i've attached it to this post - simply upload to /modules/widgets and the next time you go to the admin homepage, it should be there (assuming your admin role allows viewing of the ToDo List). i've called the file "EnhancedToDo.php", so you'll end up with two ToDo widgets on your homepage, just disable the default one using the Show/Hide widgets option top right... I could have called it ToDo.php, but then the WHMCS auto-updater would have overwritten it during the next update - so it's easier to keep it separate until WHMCS improve how they handle ToDo's. it's written for WHMCS v7.6, but will work on v7.5.x too... it might work on earlier v7 versions, but I haven't tested it on them - there is a WHMCS version check inside the widget that chooses FontAwesome 5 icons if using v7.6 or later, or FA4 if using an earlier WHMCS version. if you spot any ToDo's that don't behave correctly (e.g a third-party addon might add a ToDo that doesn't follow the WHMCS convention), then feel free to reply about it (or PM me) - it shouldn't break the output, it will likely just not show the icon(s) for that ToDo. EnhancedToDo.php
  13. 2 points
    Exactly. @Remitur The problem is that WHMCS language is based on sessions so it doesn't matter what's the URL. The article will always use the default language which in your case is English. This hook should work. I tested on my dev system lazily. I'm gonna update if it doesn't work. It's commented. More information are provided below. <?php use WHMCS\Database\Capsule; use WHMCS\Config\Setting; add_hook('ClientAreaPageKnowledgebase', 1, function($vars) { /** * The way I'm getting $ArticleLanguage looks complicated but is necessary to match "Hello hello-hello" title with the rewritten URLs "Hello-hello-hello" * In fact there's no way to distinguish real dashes "-" from fake ones added by Friendly URLs of WHMCS * Keep in mind that I'm forced to use "raw" static method since WHERE statement doesn't support complex functions like REPLACE */ // Getting title from querty string $PageName = pathinfo($_GET['rp'])['filename']; // Retreiving the language of the currently displayed article by ID and title $ArticleLanguage = Capsule::select(Capsule::raw('SELECT language FROM tblknowledgebase WHERE parentid = "' . $vars['kbarticle']['id'] . '" AND REPLACE(title, "-", " ") = "' . str_replace('-', ' ', $PageName) . '" LIMIT 1'))[0]->language; // Retreiving the default language of WHMCS from tblconfiguration $DefaultLanguage = Setting::getValue('Language'); /** * This section is optional but needed if you want to protect yourself against blackhat SEO techniques (read post for more info) */ // Retreiving default language title $LegitURL = Capsule::select(Capsule::raw('SELECT REPLACE(title, " ", "-") AS title FROM tblknowledgebase WHERE id = "' . $vars['kbarticle']['id'] . '" LIMIT 1'))[0]->title; // If the URL currently in use is not 100% legit I force a redirect to the article in default langiage if ($LegitURL !== $PageName AND !$ArticleLanguage) { header('Location: index.php?rp=/knowledgebase/' . $vars['kbarticle']['id'] . '/' . $LegitURL . '.html'); die(); } /** * Here we set the right language depending on the URL */ // I check if the $ArticleLanguage is different from the language currently in use. I also make sure that $ArticleLanguage is different from $_SESSION['Language'] to avoid infinite loops if ($ArticleLanguage != $DefaultLanguage AND $ArticleLanguage != $_SESSION['Language']) { // Set language $_SESSION['Language'] = $ArticleLanguage; // Redirect visitor to current page to re-load the correct language header('Location: index.php?rp=' . $_GET['rp']); die(); } }); add_hook('ClientAreaHeadOutput', 1, function($vars) { /** * This guy adds canonical URL inside <head></head> tag so that Google doesn't penalize you (read post for more info) */ if ($vars['templatefile'] == 'knowledgebasearticle') { $PageName = pathinfo($_GET['rp'])['filename']; $CanonicalURL = Capsule::select(Capsule::raw('SELECT REPLACE(title, " ", "-") AS title FROM tblknowledgebase WHERE (parentid = "' . $vars['kbarticle']['id'] . '" OR id = "' . $vars['kbarticle']['id'] . '") AND REPLACE(title, "-", " ") = "' . str_replace('-', ' ', $PageName) . '" LIMIT 1'))[0]->title; return '<link rel="canonical" href="index.php?rp=/knowledgebase/' . $vars['kbarticle']['id'] . '/' . $CanonicalURL . '.html"/>'; } }); Even though we're now showing the right language to visitors, Google and all other Search Engines still hate us because we're providing duplicate contents. Their hate is so strong that they penalize us on SERP. Here is why: whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-water.html whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-vodka.html whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-rum.html whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-wine.html 4 URLs, same page and (duplicate) content. The only way to avoid penalties is that we let them know what's the unique URL by using rel="canonical" tag. The above hook adds it automatically where it is supposed to be (<head>here</head>). And if you are questioning why someone should use fake links, take a look at blackhat SEO techniques. One of your malicious competitor could publish some of those fake-links so that weeks later Google & co. penalize you for duplicate content. The above hook protects you from this technique forcing a redirect to the default article in case the URL in use is not the legit one.
  14. 2 points
    Hi @crazeegeek, We've determined this could occur if the Modify Subscription feature was enabled before this feature was discontinued (only available in installations pre-2011). As a workaround, please execute the following SQL query against your WHMCS database: DELETE FROM tblpaymentgateways WHERE setting = 'modifysubscriptions' AND gateway = 'paypal';
  15. 2 points
    The guy responsible for column sorting is $_COOKIE['WHMCSSD'] that is a base64 encoded string of a json encoded object. In other words if you place this code inside your hook... <? echo '<pre>'; print_r(json_decode(base64_decode($_COOKIE['WHMCSSD']), true)); echo '</pre>'; die(); You'll get the following response: Array ( [invoices] => Array ( [orderby] => id [sort] => DESC ) ) I'm converting the object to an array just because I like it more. Anyway as soon as you open invoice.php this cookie is empty therefore the table assumes that you want to use the default sorting (Due Date DESC). Since you want to sort by ID DESC we could simply define this cookie exactly as we want. <? function admin_sort_invoices_by_id($vars) { // If current page is invoices and the cookie is still empty we define it if ($vars['filename'] == 'invoices' AND !$_COOKIE['WHMCSSD']) { setcookie('WHMCSSD', base64_encode(json_encode(array('invoices' => array('orderby' => 'id', 'sort' => 'DESC')))), time() + (86400 * 30), '/'); header('Location: invoices.php'); die(); } } add_hook('AdminAreaPage', 1, "admin_sort_invoices_by_id"); You can normally sort by other columns ASC/DESC. The only difference is that you are overriding default sorting. I tested it on one of my WHMCS and it works but I do a lot of mistakes so double-check it 😀
  16. 2 points
    there are two answers to this... firstly, there is a little known separate domain pricing page that was introduced in an earlier v7 release... it only received a passing mention by one of the WHMCS guys during a beta period, and AFAIK, it isn't officially documented... but if you go to /domain/pricing you should be able to find the page on your site - actual URL might be different depending on your Friendly URLs settings though... but that shows grace/redemption periods and fees by default. secondly, the other way would be to modify the domainregister.tpl template to show grace/redemption periods & fees - all the information is already in the array, so it's just a case of editing the template to show whatever you want to show. on a practical level, you may not be able to show grace periods as, unlike the separate pricing page, the cart will show sidebars by default and that limits the amount of space available for additional columns in the table... if it helps, i've attached a modified version of the v7.7.1 standard_cart domainregister.tpl template that shows the above output as a starting point for any changes you want to make. one other thing, again rarely mentioned in the documentation, but you can add the pricing table to the transfer page, if you want to show the user how much transfers will be per TLD.... you just need to copy the table code from domainregister.tpl to domaintransfer.tpl - probably little point in showing the featured TLDs or the categories (they wouldn't work by default as the JS is missing from the template) - but i've added the table & JS to the template and attached if others want to use it. domainregister.tpl domaintransfer.tpl
  17. 2 points
    OK thats sods law. Just got a reply from PayPal (24 hours later) It turns out that you need to disable 'Encrypted website payments' in your PayPal account settings under Settings -> My Selling Preferences -> Website preferences I don't know what happened, when this got turned on but after turning this off everything works again. I would like to also point out that all of my site and services are encrypted with a valid SSL Certificate (I just double checked everything) and I don't remember turning this on so I'm guessing that its been on since day dot or has been added by PayPal as a security thing that I missed.
  18. 2 points
    It's absolutely not true that a client with a company name is required to fill in also a Tax Number. Let me give you some examples: Required fields for Organizations: Tax number VAT number Tax number, VAT number Nothing Required fields for Companies: VAT number VAT number and Tax number (same, slightly different or completelly values) Required fields for Public Administrations: VAT number Tax number Tax number, VAT number Nothing I stop here but there are also special rules for Individuals, Sole Proprietorships, Companies listed in stock exchange, State-owned or partecipated companies or and so on. All this mess comes from my experience with a single country but you can find a lot of similarities in several European countries. I suggest you to think twice before making any change to registration form that affect all your customers indiscriminately. A field that you think is required could be optional or unknown for customers registering from other countries. Such changes should have effect on your compatriots only especially if electronic invoicing exists in your country.
  19. 2 points
    Yup, pretty much best method to cancel, refund as credit, and upgrade for them all with their knowledge of course.
  20. 2 points
    The only problem is that checkdnsrr only returns boolean and not the actual record. What I have used in the past is the PHP pear package Net_DNS2 to get the record and then you can output from there. Though I am sure there are other packages and frameworks out there.
  21. 2 points
    I assume that you realise that this code is going to get overwritten during your next WHMCS update - you'd be better off putting that code into a headoutput hook as the free addon I linked to does. the attached hook should do the same as your edited template - though obviously don't use both. facebookpixel.php
  22. 2 points
    can you go into tblconfiguration and edit that setting manually rather than using the query ?
  23. 2 points
    do you think the timing of launching a beta testing period one week before Christmas might have had something to do with that? 🙄
  24. 2 points
    many thanks @string - I was on my way out when I replied to the thread (it was Saturday night after all!) so didn't see the further questions from @mino until this morning... in case anyone else uses this hook in the future, if you wanted to hide the "Terminated" & "Cancelled" filters in the sidebar using css, you should only need to use.. #Primary_Sidebar-My_Services_Status_Filter-Terminated, #Primary_Sidebar-My_Services_Status_Filter-Cancelled {display: none;} ... i'm sure most will find that simpler than writing another hook. 🙂
  25. 2 points
    Right now, we have: - our WHMCS system in datacenter A - our DNS servers spreaded in datacenter A, B and C - our Linux hosting system in datacenter D - our Windows hosting system in datacenter E - our remote backup system in datacenter F Every datacenter is in a different country (but for A and F: same country, 250 Km of distance)
×

Important Information

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