Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 07/09/13 in all areas

  1. in v8, the summary stats were removed from the admin display - e.g Pending Orders, Overdue Invoices and Tickets Awaiting Reply - the simple hook below adds them back to the output in a similar location (top of the page)... <?php # Stats Info Bar for v8 Blend # Written by brian! use WHMCS\Database\Capsule; use WHMCS\Billing\Invoice; function admin_v8_infobar_hook($vars) { $pendingstatuslist = Capsule::table('tblorderstatuses')->where('showpending','1')->pluck('title'); $pendingorders = Capsule::table('tblorders')->whereIn('status',$pendingstatuslist)->count(); $overdueinvoices = Invoice::overdue()->count(); $awaitingreplylist = Capsule::table('tblticketstatuses')->where('showawaiting','1')->pluck('title'); $ticketsawaiting = Capsule::table('tbltickets')->whereIn('status',$awaitingreplylist)->count(); $headerreturn = '<div style="margin: 0; padding: 5px; background-color: #1a4d80; display: block; width: 100%; max-height: 20px;"> <div style="text-align: center; color: #fff; font-size: .8em; margin: 0;"> <a href="orders.php?status=Pending" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$pendingorders.'</span> '.AdminLang::trans('stats.pendingorders').'</a> | <a href="invoices.php?status=Overdue" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$overdueinvoices.'</span> '.AdminLang::trans('stats.overdueinvoices').'</a> | <a href="supporttickets.php" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$ticketsawaiting.'</span> '.AdminLang::trans('stats.ticketsawaitingreply').'</a> </div> </div>'; return $headerreturn; } add_hook("AdminAreaHeaderOutput",1,"admin_v8_infobar_hook"); this was originally written for v8.0.0 betas, but the code has now been updated for v8.0.1 (where the $sidebarstats array no longer exists and the values now have to be calculated from database queries).
    15 points
  2. 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
    14 points
  3. The WHMCS.Community is intended to provide a place for users of WHMCS to discuss, share and interact with each other as well as WHMCS Staff. To ensure we maintain a friendly environment, we ask users to respect the following rules and guidelines. Please let us know via the WHMCS.Community Assitance category should you have any questions or comments, posts in this category are visible between yourself and the WHMCS.Community Team. WHMCS reserves the right to alter these rules from time to time. 1.User Accounts Each person may have (one) 1 forum login regardless of the number of companies you may be part of. Duplicate accounts will be removed from WHMCS.Community Please do not share your user account with others - each person should retain their own username and password Usernames must not be created that contain any of the items listed below: An email address A website address The following words WHMCS cPanel Staff Moderator Admin Any word determined to cause offence or be deemed inappropriate. Usernames or Users that do not comply with these rules may be removed from WHMCS.Community 2. Behaviour on the Community We expect all users to be friendly and polite. While we understand that users will disagree and have different points of view at times, this can be communicated in a civil manner Please do not post rude, insulting or inflammatory posts. Personal attacks, name-calling and insults will not be tolerated on WHMCS.Community. Profanity and inappropriate images (including porn or gross violence) may not be posted anywhere on the WHMCS.Community. WHMCS.Community Staff & Moderators use their sole discretion as to what is deemed unacceptable behaviour in the community and may remove content at any time. Your posts assist other users, please do not delete content if you find an answer, please share this solution to help other users. 3. Advertising on WHMCS.Community Advertising, offers or self-promotion are to be posted only in the Third Party Add-ons section of the community. Community users seeking to hire a developer may post within the Service Offers & Requests section. Advertising is limited to one advertisement per seven (7) day period on a rolling 7-day basis. Additional or excessive advertising will be removed by the moderation team and your ability to post in advertising boards removed. Soliciting and/or self-promotion via the private messaging (PM) system is strictly prohibited. The sale or reselling of WHMCS Licenses is strictly prohibited on the community. Affiliate and referral links may not be used, these links are those that link to a site and contain information crediting the person with that referral 4. Posting and Moderation on WHMCS.Community The WHMCS.Community is moderated by WHMCS.Community Moderators and Staff. When a post is deemed to be in breach of the rules it will be removed and the user advised via a warning. Please do not cross-post across the community. If your topic is better suited to another section one of the WHMCS.Community team will move it to the best category for you. You may report your post if you wish to have it moved by a moderator. For privacy reasons please do not post any personally identifiable information including Usernames, Passwords, Contact Numbers, Email Addresses and/or Credit Card Numbers As WHMCS.Community is a moderated community we have implemented a Warning System. When a post is removed for breaching the community rules we’ll be sure to let you know. We allocate points to a warning and once you have a set number of points you may be suspended from posting on the community. Users that do not comply with the rules for WHMCS.Community may be banned temporarily. Ongoing temporary bans may result in a permanent ban from WHMCS.Community. The public discussion of moderation decisions is not permitted, these will be removed without notice and may result in a community ban. 5. Signature and Profile Rules Your signature may include links, however, please ensure these are reasonable (no more than 4) and they must not include Referral/Affiliate links. This includes pricing and plan details Signatures may not contain more than 4 lines at a 1024x768 resolution Please do not sell or rent your signature space, your signature is yours alone. Where your signature does not comply with these rules you may be asked to alter or remove it 6. WHMCS.Community Ranks Official WHMCS Staff & Moderators are identified by one of the following ranks located below their profile image, in addition, their posts are highlighted blue WHMCS CEO WHMCS Community Manager WHMCS Customer Service WHMCS Developer WHMCS Marketing WHMCS Staff WHMCS Support Manager WHMCS Technical Analyst WHMCS.Community runs a ranking system, new community members start with the rank of Newbie and can progress based on the number of posts, reputation points and length of time active on the community Some users have a special “Super Users” rank. These members are a select group of elite community members that are long-standing mentors in the community, courteous to other members, always providing technical insight and advice, and generally helping to make our community a better place to learn, troubleshoot and advance. The WHMCS.Community ranking formula is changed from time to time and without notice. The algorithm used is not published or discussed with users to prevent gaming the system 7. Contacting the WHMCS.Community Team You may contact a member of the WHMCS.Community via the WHMCS.Community Assitance board If you would prefer to email you may open a ticket by emailing forums@whmcs.com Thank you for helping to keep WHMCS.Community a great place
    14 points
  4. Basically, we're all being forced onto plans that are an order of magnitude more expensive with zero days notice. It's flat out fraud. We paid for a lifetime owned licence and have been paying our annual support fees for a decade, and these greedy bastards have decided that the middle of a pandemic is the perfect time to screw us all over.
    8 points
  5. Not everyone is happy with the general way v7 is going, (v6 and v5 where better) and since it seems v8 is coming next year or is planned at least. What are your main wish lists for that new version looking it from a developer or business view. What do you like WHMCS to change, improve or even remove in the future? Here is my list: More opt-in Make things more opt-in. Some things in v7 are not useful for more advanced users, like auto update, or the market store. I would like to have that stuff removed. Now I have more files and more bloat on my installation which I don't use and never will. This things should come as a separated module and if they are disabled or not installed, the code should not even be live in your server for security reasons, performance and just general simplicity. Less is more sometimes and many of those features I don't require as they are targeted to click one night operations, and not more longer power users that want to tweak and adapt WHMCS to their own operations. Bug Tracking A better bug tracker. Asking with a ticket if a bug is fixed or having to hunt down the change long on each release is painful and time consuming. Sometimes I think WHMCS as a company is very inefficient with some operations. Hiring people costs them money, so why do they want to babysit things like this. Having to answer tickets costs them time and this could be avoided with a proper bug tracker. This can't scale. Better feedback from users Feature requests. This is completely broken. Why use a different system when you have a nice community here? Build the feature requests and vote system here. If you don't want to build a bug tracker, you can even do the same here on the community for bugs and only customers with a valid license can access assuming WHMCS does not want to make this public. Slow down with features Longer releases. This could be a bit controversial but I would rather prefer WHMCS to slow down a bit. Every new release introduces more bugs than features. The Beta testing should be longer and I would be ok with maybe only 2 major releases per year. Just keep releasing patches for bugs. They are adding so many new things which are related to external services and I don't think they are aware the minefield they are creating. WHMCS should not be heavily coded to work with remote stuff. Try to build more things that work locally in your server instead of just releasing new features that require third party services. Longer Releases Longer LTS releases. They are not long releases if they only last a year. Look how Microsoft does it, 10-15 years. Or even Red Hat. The people using LTS are companies or enterprises and I'm not saying WHMCS should support them 10 years, but seriously 1 year or just a bit longer? Most developers even support their normal releases for at least 3 years. The LTS should be a minimum 3 years unless the PHP or code they rely on is not supported anymore, which is a different story. Can you imagine if everyone else did the same to WHMCS developers? Imagine if PHP was only supported 1 year, or Smarty, or anything. It would be a nightmare for them. So if they are aware that they rely on such much external code now, they should give the same considerations towards their customers. Not everyone has the time to update and make all their integrations the day they are released. This is a billing and cloud/hosting automation software. Not a blog like WordPress!!! And with that I mean security patches. Not even bug fixes. They don't have to even fix bugs or release new features on those versions. But please, at least still support them with security patches for 3 years after launch. It's the responsible thing to do. Better Mobile Mobile app is not updated for years. Show more love or open it up so we can add things. I have to rely on external services for ticket notifications and other things when this makes no sense if you have a mobile app. Instead of building things for something like Slack I'm seriously disappointed that WHMCS developers give more attention to external services then their own products. I can receive mobile notifications on third party services but not push notifications on my WHMCS mobile app. Shocking their own products are left to die. Finally, open up. You are benefiting from open source developers work but do the opposite to your own customers that are developers. Open up your code. Please just open up your code or at least the most important chunks to particular partners or companies. Make them sign what ever non disclosure agreement you want or even charge them. Your competition has none of your problems because the community can see and fix things. What is WHMCS so keen to protect here? Business users are not going to stop paying support and updates and they surely are not going to pirate the software. It's a bit childish, in particular because WHMCS would not exist today without open source work from others. WHMCS relies heavily on external third party open source code yet they even encode that. This is an insult to developers. They are taking all the code that is free and releases from other developers, and then pass Ioncube over it. One thing is protecting your code and licensing, the other thing is trying to protect code that is not even yours. WHMCS is encoding so much garbage that I'm sure this is the root of most of their bugs and problem because we cannot fix or see what they do. This is the biggest downside of using WHMCS. I don't think any serious provider will consider WHMCS for this reason. It's a blackbox. And I'm not talking here about the core, or billing stuff, or API stuff. No, WHMCS even encode things that affect your public website and cannot be easily modified or changed unless you make hacks around them software. You constantly have to intercept what WHMCS does and then transform the output because you have no idea what it does and how. It's a game I'm not willing to play in the future. Their competition advertises that they are 99% open code and only encode a few files related to the license. I don't expect WHMCS to do this but PLEASE if someone from the company is reading this, this is going to be your doom as a company in the next years. The minute competition comes up and is more open than WHMCS, those people are not coming back. Everyone is opening up in the software and technology industry. Even WHMCS would not exist as a company if it was not for other services developing API's which WHMCS is relies on for most of their connection. This is not the proper way to behave towards your developer customers. What exactly are they are trying to protect is beyond me. Even third party developers like Modules Garden and many others at least have an open version of their encoded modules. Everyone does at this point because they understand business users will not run things on their server they cannot fix, see what it does or just maintain. It's a trust thing. You would sell far more licenses and to people that actually have the money to pay. Do they distrust their own code so much? Well, the community would be able to constantly improve it with suggestions and fixes. Less work for their developers and the product would move forwards on its own. I just love how your competition works. The whole code is open, their whole bug tracker is open. This is causing frustration to those using the software and worse, forcing them to move out to custom solutions or more open platforms. WHMCS is never going to be flexible this way. And I would not complain about this if it was not for the fact that WHMCS is putting more and more code that was open in the past behind their ioncube wall. v6 and v5 had less encoded code/features, not more. I'm shocked on much WHMCS hates developers or people building their own sites around WHMCS because every new release is worse with more features behind the black box. This is now seriously affecting my business with things I cannot fix anymore or integrate. Everyone in the technology world understand proprietary standards are bad. And this is what WHMCS is doing, they are forcing people to even make simple changes using their own way of doing things. Why would I do this? Why should a PHP developer, or a HTML coder, or a JavaScript person learn how to do things the WHMCS way which is inefficient, buggy and even performs bad on a server? Those people want to use the standard coding procedures WHMCS developers use. Not the stupid hooks and API to even change something like a link. And I say stupid because this is exactly how I feel about WHMCS v7 at this point. You have to make a special PHP hook code (the WHMCS way) to change the sidebar text, colors or links. In the past I could just open the .tpl file and change it. Why? Because WHMCS is removing code from templates and putting it behind the IonCube wall. One day, the templates will be worthless and most WHMCS websites that are customized are going to be horrible slow because users have to create 240 hooks to change colors, links, or even text. Personally, I have access to all the database. And if I see v8 is not being more open but more closed. I'm moving out. I cannot trust my business operations to a company that wants to keep their customers under ransom. And this is how I feel when I cannot even fix the most simple bugs because the files are encoded. So my biggest wish list for v8 is for WHMCS to start being more open and trying to move towards that trend. They profit from open source but seem to hate open source which is a rather a strange business approach. One day, some of those developers may change their licenses and forbid their codes from being used in obfuscated software. If that day comes, WHMCS will have to remove that code from their software or change the way they work in terms of developing.
    8 points
  6. 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.
    8 points
  7. I've seen there's a feature request submitted 7 years ago about bulk auto recalculate. I know you can do that from phpMyAdmin or with a script but enough is enough. <? /** * Bulk Auto Recalculate Client Domain & Products/Services * * @writtenby Kian * */ use WHMCS\Database\Capsule; add_hook('AdminAreaHeaderOutput', 1, function($vars) { if ($vars['filename'] == 'clientssummary' AND $_GET['userid'] AND in_array($_GET['kata'], array('bulkAutoRecalculateP', 'bulkAutoRecalculateD'))) { $adminUsername = ''; // Optional for WHMCS 7.2 and later if ($_GET['kata'] == 'bulkAutoRecalculateP') { foreach(Capsule::table('tblhosting')->where('userid', '=', $_GET['userid'])->pluck('id') as $v) { localAPI('UpdateClientProduct', array('serviceid' => $v, 'autorecalc' => true), $adminUsername); } header('Location: clientssummary.php?userid=' . $_GET['userid']); die(); } elseif ($_GET['kata'] == 'bulkAutoRecalculateD') { foreach (Capsule::table('tbldomains')->where('userid', '=', $_GET['userid'])->pluck('id') as $v) { localAPI('UpdateClientDomain', array('domainid' => $v, 'autorecalc' => true), $adminUsername); } header('Location: clientssummary.php?userid=' . $_GET['userid']); die(); } } return <<<HTML <script> $(document).ready(function(){ $('[href*="affiliates.php?action=edit&id="], [href*="clientssummary.php?userid="][href*="&activateaffiliate=true&token="]').closest('li').after(('<li><a href="#" id="kata_BulkAutoRecalculate"><i class="fas fa-fw fa-sliders-h" style="width:16px;text-align:center;"></i> Bulk Auto Recalculate</a></li>')); $('#kata_BulkAutoRecalculate').on('click', function(e){ e.preventDefault(); $('#modalAjaxTitle').html('Bulk Auto Recalculate'); $('#modalAjaxBody').html('<div class="container col-md-12"><div class="row"><div class="col-md-6 text-center"><div class="panel panel-default"><div class="panel-body"><p><i class="fas fa-box fa-5x"></i></p><p><small>Auto Recalculate Customer\'s <strong>Products/Services</strong></small></p><p><a href="clientssummary.php?userid={$_GET['userid']}&kata=bulkAutoRecalculateP" class="btn btn-info btn-block">Recalculate Now »</a></p></div></div></div><div class="col-md-6 text-center"><div class="panel panel-default"><div class="panel-body"><p><i class="fas fa-globe fa-5x"></i></p><p><small>Auto Recalculate Customer\'s <strong>Domains</strong></small></p><p><a href="clientssummary.php?userid={$_GET['userid']}&kata=bulkAutoRecalculateD" class="btn btn-info btn-block">Recalculate Now »</a></p></div></div></div></div></div>'); $('#modalAjax .modal-submit').addClass('hidden'); $('#modalAjaxLoader').hide(); $('#modalAjax .modal-dialog').addClass('modal-lg'); $('#modalAjax').modal('show'); }) }) </script> HTML; });
    7 points
  8. I am more than glad to discuss this since it gives me the opportunity to prove that what moves me. Surely I'm not the best business man and developer of the world but I have a lot of direct experience since I'm playing with WHMCS since 2007. Let's go. If I had a euro for every time I heard that, I would own a Ferrari. There are probably 50k providers using WHMCS. Can you imagine how many developers and CEOs are out there? Ones that use this software on a daily basis sharing the same needs and requirements. There are many opportunities and potential customers to fulfill the growth of multiple companies. There's room for everyone. This market is rich and can provide for everyone. That being said, apart from the usual Modulesgarden and few more companies, I can't see anyone showing up with a module that solves something relevant and that is maintained for more than a couple of weeks. Why is it like this? Short answer: easier said than done & the devil is in the details. WHMCS gives people the perception to be a developer-friendly environment. One sees action hooks, API and concludes that making modules and adjustments is not a big deal till you begin coding for real and relize that this is far from being true. When I started in 2007 there were tens of developers actievely releasing modules. They all disappeared. Today there are less than 5 companies left and probably only 1 or 2 are capable of assisting you decently while they maintain their softwares in this WHMCS that keeps growing bugs, bloats and stupid ideas. It is also worth to underline that many of these companies are focusing on meeting small and trouble-free needs like creating templates, micro-management scripts, integrating some kind of services with API and payment gateways. With very few exceptions, nothing can match the complexity of Modulesgarden works. In essence we are talking about a market with almost no competition so two questions arise. First. Why in such a rich market with almost no competition and many needs that are waiting to be satisfied no one is investing money into module development? Second. If this market is rich and creating modules is easy, why Modulesgarden and others are expanding or moving to other markets? For me the answer is that creating modules for WHMCS is not like creating plugins for WordPress where tens of thousands of devs are welcome. In WHMCS no one gives a flying duck of your work. They never valued nor considered the job of third-party developers that are helping them to sell their product. This shouldn't surprise us as they don't even care about their own customers. Also don't forget that as a developer you are required to pruchase WHMCS in order to start coding. As for me, I started building this monster (Billing Extension) in 2014 exactly because I had the idea that coding in WHMCS was relatively easy and profitable. I was wrong as hell. Unfortunately I couldn't predict years or bad twists by WHMCS. To make matters worse, unlike most of my competitors, I focused on the dark side of WHMCS aiming to fix its issues and add missing features. If I could go back in time, I would stay away from billing. Profit-wise, creating a template or couple of payment gateways would have been the best decision but I don't regret it since I learned many things and met many people. So today I have a module so complex that would take a company of the size of Modulesgarden to support customers and maintain its code. I tried to scale-up. I hired developers, added more funds, merged modules rebuilding them from scratch with the same framework (1 year of work), wrote 500+ pages of docs in two languages, tried to increase prices (...) but it was still not enough. All while WHMCS from day to night release once another a version that breaks the mega-complex script that took you one month of work and that still needs to work in the old way only for people running older versions of WHMCS 🥵 After 3 consecutive years of Ok-ish results and nightmares due to WHMCS releases, I was still dealing with the same problem. I needed more funds to hire more developers but customers didn't want to support us with price increases because (I quote) «We don't need support», «Your module can't cost us more than WHMCS, Plesk or cPanel licenses», «I only use one feature». Fair enough, got it. Ironically few years later WHMCS increased prices up to $1.299.95/mo and put an end to life-time licenses 🤔 In retrospect, I should have raised prices anticipating the trend started by WHMCS, Plesk, cPanel and competitors. You can't grow customers and face increased complexity and challenges driven by poor management of WHMCS keeping the same cheap price. You end up investing tons of man-hours debugging the impossible and money doesn't grow on trees. In conclusion for me it was time to let it go. Funding such an unsustainable business just because you happen to have other sources of income doesn't make it better. You are just prolonging an agony. And for what? Cons: More nightmares, working on 25 December, at night, 12-hours per day (even 16 during emergencies 😑), being permanently unable to keep up with the so-called "stable" releases of WHMCS, receiving five new tickets every time you close one, being "stalked" and "hated" by customers, negative reviews, dealing with all the crazy stuff involving billing and e-invoicing and that unexpected change that forces you to update your module so that it works with: five, six, twentyone, ThemeMetro, Swiftmodders, bootstrap 3, 4, my uncle, my grandmother... give me a break. Pros: some profit that doesn't repay you for the toxicity you have been subjected to. In all honesty it is not worth the effort. I prefer to invest in a grid bot to buy low and sell high on a random crypto. It feels better even when I lose 1k in less than a minute. This reminds me the 2007-2012 period when I was running a quite successful game hosting provider. Everything was going fine. Good vibes, revenues, high dedication, passion for what I was doing till people started playing with ddos attacks to fulfill their egos and live the "hacker-life". At that time anti-ddos protection was very costly. I was spending 28 times the money spent by attackers to ddos me. When you spend 80% the money just to cover firewall and bandwidth costs with servers still lagging, you know it is time to sell your toy and move on. Many years later on a different market and for different reasons the story repeated with WHMCS. Ask me anything but when it comes to gameservers and WHMCS my wallet is closed and my time is better spent on a bycycle in the attempt to win a race on Zwift even if it hurts and leaves you panting like a lizard on a hot rock. Atm I' happily working on a different market that is way more complex than WHMCS but it is still more rewarding. There's a bigger pool of talents and teaching stuff is easier. Not to mention we can plan incomes, expenses and predict changes well ahead simply because there's no entity like WHMCS that feels the urge to pump out sloppy updates driven by nothing that resembles user feedback not couting shady collabs. In my opinion these are only ways to perform well as third-part developer of WHMCS: Making small scripts that are not subjected to WHMCS decisions Work for providers with deep pockets Find a way to gather tens of software developers, designers and specialistys in various fields Embracing open source hoping providers sponsor your project and that other devs come to help. If I had to choose I'd go for open source but considering risks and the fact that WHMCS doesn't care about you, why should I spend my reputation for them? Why should I keep supporting them in chains? At this point I would create my own system
    7 points
  9. You're allowing us to spread our $120 a year update payment over 12 easy monthly payments of $849.95? That's really good of you, thanks guys!!!
    7 points
  10. and the related kb article... explains why transferring owned licenses was stopped months ago.... i've still got an owned license, but I haven't used it in years - I haven't paid a penny direct to WHMCS in six years, and knowing the disgrace of what's been going on in the Support department for the last few years, that's not going to change... not removed... consolidated into one thread, but some posts will remarkably fall through the gaps and never be seen again.... I imagine the threads on WHT will be the easiest location to say whatever needs to be said. so true - the more money WHMCS users have to spend on the core product, the less they can spend on addons, customisations etc.... I can see a lot of developers moving on due to this ridiculous change.... and a lot of users switching to nulled options... *sighs* I will need to have a think over the Summer about whether it's worth carrying on supporting this nonsense - these forums have been dying over the last few years due to the neglect / incompetence of those in charge... the product is going nowhere... sadly, neither situation is going to improve any time soon.
    7 points
  11. 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
    7 points
  12. i've posted the hook for the admin info bar in the thread below - should work on both v8.0.0 and v8.0.1 🙂
    7 points
  13. Users of what? I'm thinking crack cocaine.
    6 points
  14. You can't be serious with this statement. WHMCS will run until the PHP version no longer supports it, or some security flaw comes along that you won't offer a patch for, just like the most recent one. As for "spreading the cost out over the year"? Disingenuous at best. Bring consistency for users? You've got to be kidding. This is a money grab, and a way to finally do away with the folks that thought purchase of an owned license would get them actual consistency. Little did we know that the final objective would be to get all users paying far more, "consistently", for you. Disheartening, and I'm sure it's all falling on deaf ears, since any pricing changes here will likely be upwards, and not in favor of any "grandfathered" licenses. We're being "grandfathered" in the Eskimo sense...stuck on an ice floe to drift until it melts.
    6 points
  15. <?php # Stats Info Bar for v8 Blend # Written by brian! use Carbon\Carbon; use WHMCS\Billing\Invoice; use WHMCS\Clients; use WHMCS\Database\Capsule; use WHMCS\User\Client; function admin_v8_infobar_hook($vars) { if ($vars['template'] == "blend") { $show_active_clients = true; $show_active_services = true; $show_expired_domains = false; $show_overdue_invoices = true; $show_pending_cancels = false; $show_pending_orders = true; $show_ticket_swaiting = true; $show_todo_items = false; $show_time = true; $headerreturn = '<div style="margin: 0; padding: 5px; background-color: #1a4d80; display: block; width: 100%; max-height: 20px;"> <div style="text-align: center; color: #fff; font-size: .8em; margin: 0;">'; if ($show_pending_orders) { $pendingstatuslist = Capsule::table('tblorderstatuses')->where('showpending','1')->pluck('title'); $pendingorders = Capsule::table('tblorders')->whereIn('status',$pendingstatuslist)->count(); //$pendingorders = Capsule::table('tblorders')->join('tblinvoices','tblorders.invoiceid','=','tblinvoices.id')->where('tblorders.status','Pending')->where('tblinvoices.status','Paid')->count(); $headerreturn .= '<a href="orders.php?status=Pending" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$pendingorders.'</span> '.AdminLang::trans('stats.pendingorders').'</a> | '; } if ($show_overdue_invoices) { $overdueinvoices = Invoice::overdue()->count(); $headerreturn .= '<a href="invoices.php?status=Overdue" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$overdueinvoices.'</span> '.AdminLang::trans('stats.overdueinvoices').'</a> | '; } if ($show_ticket_swaiting) { $awaitingreplylist = Capsule::table('tblticketstatuses')->where('showawaiting','1')->pluck('title'); $ticketsawaiting = Capsule::table('tbltickets')->whereIn('status',$awaitingreplylist)->where('merged_ticket_id','0')->count(); $headerreturn .= '<a href="supporttickets.php" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$ticketsawaiting.'</span> '.AdminLang::trans('stats.ticketsawaitingreply').'</a> | '; } if ($show_todo_items) { $todolistitems = Capsule::table('tbltodolist')->whereNotIn('status',['Completed'])->count(); $headerreturn .= '<a href="todolist.php" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$todolistitems.'</span> '.AdminLang::trans('stats.todoitemsdue').'</a> | '; } if ($show_active_clients) { $activeclients = Client::where('status','Active')->count(); $headerreturn .= '<a href="clients.php" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$activeclients.'</span> '.AdminLang::trans('stats.activeclients').'</a> | '; } if ($show_active_services) { $activeservices = Capsule::table('tblhosting')->where('domainstatus','Active')->count(); $headerreturn .= '<a href="'.routePath("admin-services-index").'?status=active" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$activeservices.'</span> '.AdminLang::trans('stats.activeservices').'</a> | '; } if ($show_pending_cancels) { $pendingcancels = Clients::getNumberOfOpenCancellationRequests(); $headerreturn .= '<a href="cancelrequests.php" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$pendingcancels.'</span> '.AdminLang::trans('stats.pendingcancellations').'</a> | '; } if ($show_expired_domains) { $expireddomains = Capsule::table('tbldomains')->where('status','Expired')->count(); $headerreturn .= '<a href="'.routePath("admin-domains-index").'?status=expired" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$expireddomains.'</span> '.AdminLang::trans('stats.expireddomains').'</a> | '; } if ($show_time) { $current_time = Carbon::now()->translatedFormat("l, j F Y, H:i"); $headerreturn .= $current_time; } $headerreturn .= '</div> </div>'; return $headerreturn; } } add_hook("AdminAreaHeaderOutput",1,"admin_v8_infobar_hook"); i've slightly changed the hook so that each element can now be disabled/enabled in the settings, e.g if you didn't want to show 'Pending Orders', then you would change... $show_pending_orders = true; to... $show_pending_orders = false;
    6 points
  16. Lagom WHMCS Email Template - FREE We’ve just released a Lagom WHMCS Email Template, it’s available in our store completly for Free!! With active license of Lagom WHMCS Theme you will gain access to the simple email template management from the WHMCS addon. You won’t need to have any HTML and CSS knowledge, to customize the Lagom WHMCS Email Template to your needs. You can choose from 3 styles: Futuristic Style - live demo Depth Style - live demo Minimal Style - live demo Lagom Extension Configure Header Text Configure Social Links Configure Footer Links Choose Style Live Preview
    6 points
  17. Hello there, After a lot of thinking, here you have a template for the Upcoming Domain Renewal Notice that will cover all scenarios. Subject: Domain {$domain_name} is due to expire in {$domain_days_until_expiry} days Dear {$client_name}, Domain {$domain_name} is due to expire in {$domain_days_until_expiry} days - {if $domain_do_not_renew eq "0"}Auto Renew On{else}Auto Renew Off{/if}. {if $domain_days_until_expiry eq "60"}{if $domain_do_not_renew eq "0"}As you have Auto Renew On, you will receive the renewal invoice 30 days before the expiration date.{else}If you would like to have the domain renewed, please access client area and turn On the Auto Renew option.{/if}{else}{if $domain_do_not_renew eq "0"}As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration.{else}To renew the domain, please click on the following url {$domain_renewal_url}.{/if}{/if} {if $domain_days_until_expiry eq "7"}If domain {$domain_name} expires, the website and emails using this domain will no longer work.{/if} {if $domain_days_until_expiry eq "3"}If domain {$domain.name} expires, the website and emails using this domain will no longer work, and the domain may be available to be registered by someone else. WARNING: To renew an expired domain, when possible, you may have to pay a fee of up to $250.{/if} Explanation If you have configured the First Renewal Notice to be sent 60 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 60 days - Auto Renew On. As you have Auto Renew On, you will receive the renewal invoice 30 days before the expiration date. If you have configured the First Renewal Notice to be sent 60 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 60 days - Auto Renew Off. If you would like to have the domain renewed, please access client area and turn On the Auto Renew option. If you have configured the Second Renewal Notice to be sent 30 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 30 days - Auto Renew On. As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration. If you have configured the Second Renewal Notice to be sent 30 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 30 days - Auto Renew Off. To renew the domain, please click on the following url {$domain_renewal_url}. If you have configured the Third Renewal Notice to be sent 7 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 7 days - Auto Renew On. As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration. If domain example.com expires, the website and emails using this domain will no longer work. If you have configured the Third Renewal Notice to be sent 7 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 7 days - Auto Renew Off. To renew the domain, please click on the following url {$domain_renewal_url}. If domain example.com expires, the website and emails using this domain will no longer work. If you have configured the Fourth Renewal Notice to be sent 3 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 3 days - Auto Renew On. As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration. If domain example.com expires, the website and emails using this domain will no longer work, and the domain may be available to be registered by someone else. WARNING: To renew an expired domain, when possible, you may have to pay a fee of up to $250. If you have configured the Fourth Renewal Notice to be sent 3 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 3 days - Auto Renew Off. To renew the domain, please click on the following url {$domain_renewal_url}. If domain example.com expires, the website and emails using this domain will no longer work, and the domain may be available to be registered by someone else. WARNING: To renew an expired domain, when possible, you may have to pay a fee of up to $250. I hope that this will be useful for someone. Best regards, David Duarte
    6 points
  18. https://docs.whmcs.com/Changelog:WHMCS_V7.6 if you want to edit the template, you could always use {$smarty.now} to add a timestamp as the hostname... not random, but unless you get 2 users ordering at exactly the same time, it should work... alternatively, you could use a ClientAreaPageCart hook, generate a random string, optionally check that it hasn't been previously used in the db, and then pass it back to the template as $server.hostname - but if you've already edited the template to add the other NA values, then you might as well just edit the template one more time! 😀
    6 points
  19. The one I use won't work for most people because it uses PHPMailer with SMTP, but here's a simple version using the PHP mail() function: <?php /* This script is designed to keep the table tbllog_register in WHMCS from getting huge from creating a record every five minutes when cron runs. Fill out the database variables for your WHMCS installation and the $to email address where you want the script to send you notices. I recommend naming the script "clean_whmcs_logs.php" and putting it in a folder outside of your /public_html folder, then giving it 600 permissions since it will contain a database username and password as well as an email address. If you name it as above you can run the script in cron once a week with the command: php -q /<path to your scripts folder>/clean_whmcs_logs.php >/dev/null 2>&1 The script will send you an email if there is a connection problem, and on completion. */ // ******************************** DATABASE VARIABLES ********************************************* $host = 'localhost'; $dbname = ''; // The name of your WHMCS database. $dbuser = ''; // The username for your WHMCS database. Only DELETE capability is necessary for this script. $dbpass = ''; // The password for your WHMCS database user. // ***************************** END DATABASE VARIABLES ******************************************* // ******************************* EMAIL SETTING(S) ************************************************* $to = ''; // The email address where you want notices sent. // ***************************** END EMAIL SETTINGS ************************************************ function MailNotice($subject, $message) { global $to; $message = wordwrap($message, 70, "\r\n"); if (!mail($to, $subject, $message)) { error_log('The script clean_whmcs_logs.php was unable to send a notice email: ' . $message); } } // Set the cutoff date for selecting/deleting records to two weeks ago. $date = date('Y-m-d', strtotime('-2 weeks')); // Delete the records prior to the $date. $sql = "DELETE FROM tbllog_register WHERE created_at < :date"; try { $dbh = new PDO('mysql:host=' . $host . ';dbname=' . $dbname, $dbuser, $dbpass); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sth = $dbh->prepare($sql); $sth->bindParam(':date', $date); $sth->execute(); $deleted = $sth->rowCount(); MailNotice('Clean WHMCS Logs Notice', 'Clean WHMCS Logs ran successfully, deleting ' . $deleted . ' records.'); } catch(PDOException $e) { MailNotice('PDO Error on Line 52', $e->getMessage() . ' with sql = ' . $sql); } ?> clean_whmcs_logs.php
    6 points
  20. Hi Friends, I have found some users that may need to add certain HTML code for many different reasons to the client area of WHMCS. This could be for tracking code, Google tag manager or a custom Live chat addon that you need to ensure their custom HTML code is added to a certain section on the page via HTML or JS code per the instructions of what you are adding to the client area pages. The best way to achieve this would to use a custom hook. Depending on where you need to place your HTML code on the page, you would use one of the below hooks: If you want to add HTML code to be placed in the <head> section of the page your would use the ClientAreaHeadOutput hook. If you want to add HTML code to be placed in the <body> section of the page you would use the ClientAreaHeaderOutput hook. If you want to add HTML code to be placed in the <footer> section of the page you would use the ClientAreaFooterOutput hook This assumes you are already familiar with creating hooks. For further information to learn how to create hooks please review the following developers documentation: https://developers.whmcs.com/hooks/getting-started/ Once your hook is saved under your /includes/hooks/ directory in your WHMCS installation, you can use the use your browsers developer tools to Inspect the client area pages to check that your code has be inserted where it needs to be placed or where you wanted it to be placed on the page. Instructions: I have provided example snippets below for creating a hook for each section to add HTML code to the client area pages for the <head>, <body> or <footer> sections of the client area pages after the PHP has been rendered. All you will need to do is insert your HTML code in between the <!-- Start insert code here --> and <!-- End insert code here --> comments in the below examples. ClientAreaHeadOutput Hook Example: The code you place in between the comments referenced above will add your HTML code to the <head> section of every client area page: <?php /** * The code below will be added in the <head> section * @author WHMCS Danny */ add_hook('ClientAreaHeadOutput', 1, function($vars) { return <<<HTML <!-- Start insert code here --> <!-- End insert code here --> HTML; }); Source: https://developers.whmcs.com/hooks-reference/output/#clientareaheadoutput ClientAreaHeaderOutput Hook Example: The code you place in between the comments referenced above will add your HTML code to the <body> section of every client area page: <?php /** * The code below will be added in the <body> tag section * @author WHMCS Danny */ add_hook('ClientAreaHeaderOutput', 1, function($vars) { return <<<HTML <!-- Start insert code here --> <!-- End insert code here --> HTML; }); Source: https://developers.whmcs.com/hooks-reference/output/#clientareaheaderoutput ClientAreaFooterOutput Hook Example: The code you place in between the comments referenced above will add your HTML code to the <footer> section of every client area page: <? /** * The code below will be added to the <footer> tag section * @author WHMCS Danny */ add_hook('ClientAreaFooterOutput', 1, function($vars) { return <<<HTML <!-- Start insert code here --> <!-- End insert code here --> HTML; }); Source: https://developers.whmcs.com/hooks-reference/output/#clientareafooteroutput I hope this information helps anyone who is looking on how to add HTML/JS code to your WHMCS client area, such as, a tracking code, Google tag manager or a custom Live Chat addon etc. Best Regards, - WHMCS Danny
    5 points
  21. No, I do not. This is a discussion board and I believe I have answered your questions, I've given advice around the PHP modules and Nginx configurations. A simple thank you for my contribution would be nice, but hey ho 🤐👇 I understand you can install Nginx, PHP and MySQL. But lets take it from the start.. Update and upgrade your packages: sudo apt update sudo apt upgrade Install Nginx and start it: sudo apt install nginx sudo systemctl start nginx sudo systemctl enable nginx Install, start and set up MariaDB: sudo apt install mariadb-server sudo systemctl start mariadb sudo systemctl enable mariadb sudo mysql_secure_installation Install dependencies: sudo apt install ca-certificates apt-transport-https software-properties-common wget curl lsb-release Import a repository for PHP 8.1 and then update and upgrade packages again: curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x sudo apt update sudo apt upgrade Install PHP 8.1 and then start FPM and check its running: sudo apt install php8.1 php8.1-fpm php8.1-cli sudo systemctl start php8.1-fpm sudo systemctl enable php8.1-fpm sudo systemctl status php8.1-fpm Install the extensions required by WHMCS: sudo apt install php8.1-curl php8.1-gd php8.1-xml php8.1-common php8.1-mbstring php8.1-gmp php8.1-bcmath php8.1-intl php8.1-zip php8.1-mysql php8.1-soap Download and extract ioncube loaders: cd /tmp wget https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz tar -zxvf ioncube_loaders_lin_x86-64.tar.gz Get your PHP extension path: php -i | grep extension_dir >> extension_dir => /usr/lib/php/20210902 => /usr/lib/php/20210902 Copy the correct loader to your extensions directory: sudo cp /tmp/ioncube/ioncube_loader_lin_8.1.so /usr/lib/php/20210902 Add the extension to your php.ini file (you may also want to add it to /etc/php/8.1/cli/php.ini) : sudo nano /etc/php/8.1/fpm/php.ini zend_extension = /usr/lib/php/20210902/ioncube_loader_lin_8.1.so Restart PHP FPM: sudo systemctl restart php8.1-fpm Set up your Nginx configuration file (in my example debian.leemahoney.cloud) : sudo nano /etc/nginx/sites-available/debian.leemahoney.cloud server { listen 80; server_name debian.leemahoney.cloud; root /var/www/html; access_log /var/log/nginx/debian.leemahoney.cloud-access_log; error_log /var/log/nginx/debian.leemahoney.cloud-error_log; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; index index.php index.html index.htm; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; proxy_send_timeout 300s; proxy_read_timeout 300s; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /announcements/?(.*)$ { rewrite ^/(.*)$ /index.php?rp=/announcements/$1; } location ~ /downloads/?(.*)$ { rewrite ^/(.*)$ /index.php?rp=/downloads/$1; } location ~ /knowledgebase/?(.*)$ { rewrite ^/(.*)$ /index.php?rp=/knowledgebase/$1; } location ~ /\.(?!well-known).* { deny all; } location ^~ /vendor/ { deny all; return 403; } location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|svg|woff|woff2|ttf)\$ { expires 1M; access_log off; add_header Cache-Control "public"; } location ~* \.(?:css|js)\$ { expires 7d; access_log off; add_header Cache-Control "public"; } location ~ /\.ht { deny all; } } Modified from https://gist.github.com/Bharat-B/6ba2e18f85591c77fdf00ad7334fb9c6 and https://gist.github.com/Bharat-B/62205bfd1dbe6d7ac9e24973c2bfd47e Enable the configuration file and reload Nginx: sudo ln -s /etc/nginx/sites-available/debian.leemahoney.cloud /etc/nginx/sites-enabled/debian.leemahoney.cloud sudo systemctl reload nginx Optionally install a free SSL on the domain: sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d debian.leemahoney.cloud Create a database and a user for WHMCS: sudo mysql -u root -p >> create database whmcs; >> create user whmcsuser@localhost identified by 'mystrongpassword'; >> grant delete, insert, select, update, lock tables, alter, create, drop, index on whmcs.* to whmcsuser@localhost; >> flush privileges; >> exit Download WHMCS v8.6 to your /var/www/html folder and enjoy. (will not work on versions prior due to PHP 8.1) Ps, don't forget to change permissions on your html folder: sudo chown -R $USER:$USER /var/www/html There's some obvious further steps such as securing directories, setting up a firewall and allowing Nginx through it etc... to follow, but the above steps will get you started. You're welcome.
    5 points
  22. You completely missed my point John. The program has always been marketed as requiring the licenses to be sold bundled with hosting services even to this day your reseller program page confirms this. This is the reason I have ruled out your reseller program for the last 11 years. Theme Metro are bundling the license with templates, not hosting services. So why have they been approved?
    5 points
  23. Although it seems small but for us the users every extra action we need to do is important. Please bring back the fixed search box as I am sure every one is using it many times everyday. Thank You Giora
    5 points
  24. You must be new here. They don't care about loyal customers but money. Many of us here are loyal to the brand for years and have tried to help others, as well wasted countless hours trying to make WHMCS better. We always got silence. WHMCS will not change because a few customers whine about pricing. Their already huge and are making more profit every year. They don't want lousy customers paying a few bucks a month. I don't think you understand what WHMCS wants as a company. They want to move into a leased SaaS model, one you will have to pay them a share of your profits, for every customer and every thing you sell. Why else do you think they even launched something like the MarketConnect...
    5 points
  25. Chris, Do you consider a price increase of 85x to be reasonable? Also on the new pricing, once you go 1 customer over 10k, your price goes from $249 to $849? Can you just admit what's going on, which is a huge, greedy cash grab. I've never even heard of a price increase of around 8400% before. There is literally no justification for it, you know it, we all know it.
    5 points
  26. the most positive spin you can put on the last 24 hours is that someone at WHMCS handled the announcement process very very badly... i'm struggling to think of a worse example of how to announce something like this. judging by the vast number of emails I received this morning, I think a lot of users have now passed the point of no return and will move on elsewhere - I don't blame them. btw - I suspect the timing of the announcement might be linked to it being the first day of the UK tax year.... either that, or it was a remarkable coincidence. absolutely he knows - either that, or he's a puppet who's not really in charge... can't have it both ways. it's too late now, but he would have been better served spending less time hiding behind blog posts, and more time reading/posting in this place, and not delegating the responsibility to others who don't have the authority to say boo! and can only reel out the copy&paste corporate sentences.
    5 points
  27. So, let me get this straight..... We took a chance years ago to support a budding WHMCS by shelling out for a lifetime license. THEN, we pay our annual support fees for YEARS, NOW, we are being forced to pay monthly? What the hell man, this is how you treat your early adopters and supporters? This is very cPanelish in that loyal customers are just being made to swallow higher prices as a reward for their loyalty.......
    5 points
  28. Hello @Stuart Newton These table records data relate to cron. Basically, it is where the results of a cron task are stored. The daily cron email report aggregates its content from these rows. At present it is not possible to prune this log from within WHMCS, however in 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 you did want to do this, you could so with a SQL query. For example the SQL query below will remove any entries in that table that predate 2020: DELETE FROM `tbllog_register` WHERE created_at < "2020-01-01"; As always please backup your WHMCS DB before perfoming such operations. I hope this information helps.
    5 points
  29. When choosing a product that has a recurring billing cycle, WHMCS will show the price in one of two fixed ways – depending on whether the "Monthly Pricing Breakdown" checkbox is ticked in the "Ordering" settings tab within the Admin Area. If it is not ticked, then the price will be displayed alongside the cycle names (taken from the language files) for the available cycles – if there are setup fees included for the cycle, they will be added to the end of the text (shown below on the left). However, if the checkbox is ticked, then WHMCS will not display the total cost of the cycles, but will calculate an equivalent monthly price for each of them instead (shown below on the right). A question was asked in the Community Forum by Ambarella about how to show the total price, the saving from the minimum cycle and also the monthly price for each cycle – e.g. for a layout such as this: http://forum.whmcs.com/showthread.php?84298-How-to-display-discounted-pricing-on-order-pages I was intrigued to see if there was an answer to this question as it has previously been asked many times and as far as I could tell, never really answered. Unfortunately, it is not possible to do this solely by changing any admin settings – the above two methods for displaying the cost of recurring billing cycles are hard-coded into WHMCS. If we were looking to only make a minor change to either layout, it would be possible to do so by slightly modifying the language files and tweaking the existing billing cycle variable in the template. However, Ambarella’s desired layout uses aspects of both methods and then additionally wishes to show the saving too - minor tweaking wouldn’t be sufficient to do this and so a more thorough solution has to be developed. The final solution turned out to be far simpler, from a coding point of view, than I had first imagined as most of the required variables were easily obtainable. I have also tried to keep it flexible and simple enough for others to modify for their own needs. This has been tested using the latest release of WHMCS as I write this, v5.3.4, and will work with all of the default order form templates (Ajaxcart, Boxes, Cart, Comparison, Modern, Slider, Verticalsteps and Web20Cart). If they’re similar in design to the default templates, I can see no reason why this solution shouldn’t work with customised order form templates either. There are three steps to this solution, listed below, and I will go through each of them briefly before bringing them all together to show the completed result. Possible changes to the language file(s). Creation of the new variables to calculate and store the required values. Modifying the template to use these new variables. Language Files The two default methods for showing recurring billing cycles use existing language variables in their display. When “Monthly Pricing Breakdown” is enabled, the following variables are used. In the example below, this is their values from the english.php language file: $_LANG['orderpaymentterm1month'] = "1 Month Price"; $_LANG['orderpaymentterm3month'] = "3 Month Price"; $_LANG['orderpaymentterm6month'] = "6 Month Price"; $_LANG['orderpaymentterm12month'] = "12 Month Price"; $_LANG['orderpaymentterm24month'] = "24 Month Price"; $_LANG['orderpaymentterm36month'] = "36 Month Price"; When disabled, it uses the following variables: $_LANG['orderpaymenttermmonthly'] = "Monthly"; $_LANG['orderpaymenttermquarterly'] = "Quarterly"; $_LANG['orderpaymenttermsemiannually'] = "Semi-Annually"; $_LANG['orderpaymenttermannually'] = "Annually"; $_LANG['orderpaymenttermbiennially'] = "Biennially"; $_LANG['orderpaymenttermtriennially'] = "Triennially"; Ideally, if you can use any of the above groups of variables without modifying them, then it is probably easier to do so. But if you feel that you need to modify any of them for use with this method, I would strongly urge you to consider the consequences carefully before doing so. The second group of variables (Monthly, Quarterly, Semi-Annually etc) are also used on the cart summary page, viewcart.tpl, and so any changes you make to them for use in the billing cycle page, will also affect their display on the cart summary page too. As an aside, I should probably add that if your WHMCS site only uses one language, then you could code the language directly in the template rather than using language variables – but for the sake of this tutorial, I will assume you are not and use the language files. Using the example of Ambarella’s desired output of "Monthly Cost", "Quarterly Cost" etc, you might think that it would be easier to use the existing variable for "Monthly", add another variable to store "Cost" - then use them together. While this might work in English, it would not necessary be grammatically correct in other languages – for example, in the French.php language file, the value for "Monthly" is: $_LANG['orderpaymenttermmonthly'] = "Mensuel"; The French word for "Cost" is "coût" – so if we put them together, we would get "Mensuel coût". Using my (limited!) understanding of French, I think that it should really be "coût mensuel" – and this appears to be confirmed by Google Translate. So to make things easier, we will start by creating six new language variables for use with this recurring billing cycle solution and add them to the language override file(s). Language Overrides Although we can edit the existing language files in WHMCS, it is recommended that you do not because when you update WHMCS, you will overwrite these language files – and subsequently lose any changes that you have made to them. http://docs.whmcs.com/Language_Overrides To create a Language Override file, we would follow this procedure: Create the folder 'overrides' within the 'lang' folder. Create or copy the language file you want to override. For example, to create an override for the French language you create ./lang/overrides/french.php Open the newly created file in your preferred editor. Start the file with a PHP tag '<?php' indicating PHP code is to be used. Try to use variable names that make sense to where they’re being used, and have not previously been used. So, for our six recurring billing cycles, let’s use the following: $_LANG['billingcyclemonth'] = "Monthly Cost"; $_LANG['billingcyclequart'] = "Quarterly Cost"; $_LANG['billingcyclesemi'] = "Semi-Annual Cost"; $_LANG['billingcycleannual'] = "Annual Cost"; $_LANG['billingcyclebienn'] = "Biennial Cost"; $_LANG['billingcycletrienn'] = "Triennial Cost"; To get Ambarella’s output, we will need two additional new language variables – one for “Saving” and another for “Per Month”. $_LANG['cyclesaving'] = "Save"; $_LANG['permonth'] = "P/m"; Now that we have these language variables created, we can move on to making the calculations and saving them for use in the display. Calculations and Variables As the template system used by WHMCS is based on Smarty, I have used only Smarty code for this solution. It would be possible to perform these calculations using PHP within the template, but it is often frowned upon to use {php} tags in the templates. Also, I believe that as of Smarty v3, the option to do use {php} has been removed. Although WHMCS currently uses Smarty v2, I am sure that at some point it will be upgraded. Therefore, as it should be easier for others to follow, and hopefully avoid future upgrade complications, I decided to write the solution entirely using Smarty tags. We need to calculate the saving of a recurring billing cycle compared to the minimum billing cycle – this would probably be the monthly cycle, but this is not always the case. Usefully, the variable that stores the minimum billing cycle is available to us and so we can use it in our calculations to determine the correct savings for each enabled recurring billing cycle based on the minimum cycle. Additionally, we need to calculate the price per month of a recurring billing cycle – but this is simple as it is just the total price for the billing cycle divided by its total number of months. So let’s start with the easier step first – calculating the price per month of a cycle. Obviously, we don’t have to calculate the price per month for the monthly cycle, so we just need to work out the other five. For this we need two variables - the total billing cycle cost (which we can obtain from existing variables) and the number of months in each cycle (which we will define ourselves). First, we create a new variable and give it a value of zero to ensure that any calculations are not added to any previous total. Then, using the {math} Smarty tag, we assign our result to this variable; define what the equation is; specify the variables we’re using in the equation and set the format of the resulting answer... and then repeat the same process for the remaining recurring billing cycles. {assign var="qmonthprice" value=0} {math assign="qmonthprice" equation="d / b" b=3 d=$pricing.rawpricing.quarterly format="%.2f"} {assign var="smonthprice" value=0} {math assign="smonthprice" equation="d / b" b=6 d=$pricing.rawpricing.semiannually format="%.2f"} {assign var="amonthprice" value=0} {math assign="amonthprice" equation="d / b" b=12 d=$pricing.rawpricing.annually format="%.2f"} {assign var="bmonthprice" value=0} {math assign="bmonthprice" equation="d / b" b=24 d=$pricing.rawpricing.biennially format="%.2f"} {assign var="tmonthprice" value=0} {math assign="tmonthprice" equation="d / b" b=36 d=$pricing.rawpricing.triennially format="%.2f"} The above code will create the price per month for each recurring billing cycle and store it to two decimal places. Next we need to calculate the savings – this uses a similar method to the previous example, but there are more variables required and thus the equation itself is more complicated - we will also use an {if} statement to determine what the minimum billing cycle is. To calculate the saving, we also take into account any setup fees for each cycle. For the previous “price per month” calculation, I have ignored any setup fees – but these could easily be added by modifying the previous equations if you wished to include them. As the minimum billing cycle increases, there are fewer additional cycles available and so fewer calculations will be required. For "Monthly", there are five saving calculations to be made – but by the time the minimum cycle is "Biennial", there is only one calculation required. If the minimum billing cycle is "Triennial", then it will not necessary to calculate any savings as there will only be one recurring billing cycle available. Here is a small example of the required code... {if $pricing.minprice.cycle eq "monthly"} {assign var="qsaving" value=0} {math assign="qsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=3 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.quarterly e=$pricing.rawpricing.qsetupfee format="%.2f"} {/if} The above code will calculate the savings for the quarterly billing cycle based on the minimum billing cycle being monthly, and store it to two decimal places. So we have our modified language variables; we have created our equations to calculate the price per month / cycle savings and assigned them to new variables – the third step is to integrate these into the templates. Template Modifications As I stated earlier in this tutorial, this solution will work for all of the default order form templates and should work for customised order form templates too. While there might be slight variations in the code used to create the billing cycle table in the different order form templates, the six important variables remain the same – and it is only these that you will need to replace with my new code. If we use "Comparison" as an example and look at the current code for displaying the monthly cycle: {if $pricing.monthly}<tr><td class="radiofield"> <input type="radio" name="billingcycle" id="cycle1" value="monthly"{if $billingcycle eq "monthly"} checked{/if} onclick="submit()" /></td><td class="fieldarea"><label for="cycle1">{$pricing.monthly}</label></td></tr>{/if} To use the new modified code to display our customised layout, you need to replace the above with: As you can see, the basics of the layout remain exactly the same, all we have done is replaced {$pricing.monthly} with the following: {$LANG.billingcyclemonth} {$currency.prefix}{$pricing.rawpricing.monthly}{$currency.suffix}{if $pricing.rawpricing.msetupfee neq 0} + {$currency.prefix}{$pricing.rawpricing.msetupfee}{$currency.suffix} {$LANG.ordersetupfee}{/if} Some of these variables you will recognise as we have created them previously – the others are defined by WHMCS, either to store price / setup fee values, or currency strings. {$currency.prefix} - The prefix defined in your currency settings, e.g. $, £, € etc or left blank. {$currency.suffix} - The suffix defined in your currency settings, e.g. USD, GBP, EUR etc or left blank. If we take a look at the next billing cycle, in this case quarterly, you will see some additional code that will generate the saving text (which obviously is not used on the minimum billing cycle). After adding the code for the remaining billing cycles, the output using the Comparison order form would be as follows: In the above examples, I’ve intentionally setup some billing cycles to have setup fees and others not – this was to thoroughly test the equations used. So that’s a brief explanation of the theory, next we will assemble the three steps and bring them together for the finished solution. Language Files As I previously listed, here are the eight new language variables - if you want to use them, remember to add them to your language override file(s). Should you need to add more or change these, please do so! $_LANG['billingcyclemonth'] = "Monthly Cost"; $_LANG['billingcyclequart'] = "Quarterly Cost"; $_LANG['billingcyclesemi'] = "Semi-Annual Cost"; $_LANG['billingcycleannual'] = "Annual Cost"; $_LANG['billingcyclebienn'] = "Biennial Cost"; $_LANG['billingcycletrienn'] = "Triennial Cost"; $_LANG['cyclesaving'] = "Save"; $_LANG['permonth'] = "P/m"; Calculations and Variables If you require calculations and new variables for your solution, add them to the template before the lines in which these newly created variables are called. For this solution, we will need to add the following to the 'configureproduct.tpl' order form template(s) *before* the template modifications of step 3. {* Calculate the price per month *} {assign var="qmonthprice" value=0} {math assign="qmonthprice" equation="d / b" b=3 d=$pricing.rawpricing.quarterly format="%.2f"} {assign var="smonthprice" value=0} {math assign="smonthprice" equation="d / b" b=6 d=$pricing.rawpricing.semiannually format="%.2f"} {assign var="amonthprice" value=0} {math assign="amonthprice" equation="d / b" b=12 d=$pricing.rawpricing.annually format="%.2f"} {assign var="bmonthprice" value=0} {math assign="bmonthprice" equation="d / b" b=24 d=$pricing.rawpricing.biennially format="%.2f"} {assign var="tmonthprice" value=0} {math assign="tmonthprice" equation="d / b" b=36 d=$pricing.rawpricing.triennially format="%.2f"} {* Calculate the cycle savings *} {if $pricing.minprice.cycle eq "monthly"} {assign var="qsaving" value=0} {math assign="qsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=3 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.quarterly e=$pricing.rawpricing.qsetupfee format="%.2f"} {assign var="ssaving" value=0} {math assign="ssaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=6 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.semiannually e=$pricing.rawpricing.ssetupfee format="%.2f"} {assign var="asaving" value=0} {math assign="asaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=12 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.annually e=$pricing.rawpricing.asetupfee format="%.2f"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=24 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=36 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "quarterly"} {assign var="ssaving" value=0} {math assign="ssaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=2 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.semiannually e=$pricing.rawpricing.ssetupfee format="%.2f"} {assign var="asaving" value=0} {math assign="asaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=4 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.annually e=$pricing.rawpricing.asetupfee format="%.2f"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=8 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=12 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "semiannually"} {assign var="asaving" value=0} {math assign="asaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.semiannually b=2 c=$pricing.rawpricing.ssetupfee d=$pricing.rawpricing.annually e=$pricing.rawpricing.asetupfee format="%.2f"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.semiannually b=4 c=$pricing.rawpricing.ssetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.semiannually b=8 c=$pricing.rawpricing.ssetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "annually"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.annually b=2 c=$pricing.rawpricing.asetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.annually b=3 c=$pricing.rawpricing.asetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "biennially"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.biennially b=1.5 c=$pricing.rawpricing.bsetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {/if} Template Modifications In the previous step, we modified the 'configureproduct.tpl' to calculate and assign some new variables. Next, we will replace the existing recurring billing cycle code in that same template file with the new code. To make this solution complete, I will go through the default order form templates and show the existing code, plus the new code to replace it with. Ajaxcart The default recurring billing cycle code for Ajaxcart (configureproduct.tpl) is... Replace the above with the new modified code... Please note: This code appeared not to work in v5.3.3, but following the v5.3.4 maintenance release, the pricing bugs have been fixed in WHMCS and this solution now works using Ajaxcart in v5.3.4 Boxes The original code and the replacement code are the same as for Ajaxcart. Cart The original code and the replacement code are the same as for Ajaxcart. Comparison The default recurring billing cycle code for Comparison (configureproduct.tpl) is... Replace the above with the new modified code... Modern & Slider The default recurring billing cycle code for Modern & Slider (configureproduct.tpl) is... Replace the above with the new modified code... Verticalsteps The original code and the replacement code are the same as for Ajaxcart. Web20Cart The original code and the replacement code are the same as for Ajaxcart. Taking the solution to the next level During this tutorial, I’ve shown how, instead of using either of the default WHMCS predefined displays of recurring billing cycles, we can define and use our own specified layout. But, why stop there? Now that we are no longer constrained by hardcoded displays, we could take this further and make other changes... some trivial, others cosmetic and perhaps one or two that are very powerful! Ok, let’s start off with something trivial that you can use on those templates that don’t have a dropdown to display the cycles – e.g., Comparison, Modern and Slider. If you wanted to bold the billing cycle names, and perhaps highlight any potential savings by showing them in red, you could use the following code: When originally working out the Smarty code for this tutorial, I did consider using combined variables as WHMCS currently does, e.g $pricing.monthly etc, where a number of variables are assembled together to create a single easily callable variable. However, I decided against doing this for a number of reasons – firstly, I wanted to show all the component variables separately to make it easier for others to remove or add variables themselves; Secondly, because the variables are separate, each can be modified (either with Smarty code or as with the above html/css) individually and thirdly, in most circumstances I can foresee with this, I don’t think there’s any real advantage in doing so! So we’ve modified the display a little, but why don’t we try to do something a little more powerful! Up until this point, we have simply been replacing the default method of displaying the recurring billing cycles with our customised solution - but if we can create one solution, why not a second, a third or a hundred? We are now in a position where, instead of WHMCS just using one recurring billing cycle display method for the entire site, we can specify different cycle displays for each product and/or product group. Put simply – each individual product or product group can use its own method for displaying recurring billing cycles, as defined by you! The code itself is straightforward and uses the variables for Group ID (gid) and Product ID (pid) – these values can be obtained from the “Direct Cart Links” section of the Product or Product Group in the Admin Area - http://docs.whmcs.com/Products_and_Services#Links_tab As an example, let’s use Ajaxcart and specify a custom display method for one product – all other products will use the default method of display (in practice this could be another custom layout, but to save time and keep things simple, we’ll use the default display code). in basic terms, this: In actual code... If you wanted to select product groups and individual products to use the same display method, then you could use... You can add as many products and/or groups you want to the above statement or use multiple {if} statements - just remember to end the block of code with a closing {/if}, This advanced solution should hopefully allow you to make the shopping process slightly easier for your customers by enabling you to use more appropriate billing cycle text for each product and/or group. I suspect that I've only scratched the surface of what is possible with this technique... so if anyone turns this into a commercial addon, I'd appreciate a share of the profits, a mention - or at the very least, a small glass of cooking sherry to get me through the day.* * I'd add a smilie at this point, but I'm limited to ten images and can't add one! lol
    5 points
  30. just a heads up that yesterday evening I figured out a viable method to reset any user's password... it works! 🎉 over the weekend, i'm going to try to turn it into a workable solution for others to use from the admin area.
    5 points
  31. in v7 and earlier, you could right-click on the "Login As Client" link and open it in a new tab - useful if you need to see both admin and client areas at the same time. in v8, "Login As Owner" now uses a form and you can't right-click on it to open a new tab... *sighs* 🙄 so the simple hook below will open that link in a new tab by default... <?php # Login As Owner Open In New Tab Hook # Written by brian! function admin_login_as_owner_hook($vars) { if ($vars['filename'] == 'clientssummary' && isset($_GET["userid"])) { return '<script>$("#frmLoginAsOwner").prop("target","_blank");</script>'; } } add_hook("AdminAreaFooterOutput", 1, "admin_login_as_owner_hook"); you could edit the clientssummary.tpl template too and just add the target link to the form code.
    5 points
  32. that's a panic attack - nothing to be frightened or overly concerned about... I mean it's not ideal if you have them whilst driving, but it's just the body's way of telling you that you're under stress / emotional and potentially bottling it up. if it helps, it happened to me back in early 2010 - never while driving, but when I went shopping or the theatre (bizarrely!) - genuinely the most frightening situation as I thought I was going mad. I went to the doctor about it and the short-term help was beta-blocker medication for anxiety... although I never finished the prescription as I only took them occasionally - I still keep the box nearby to remind me of those times.... I can look back and laugh at it now. 🤪 the longer-term solution (had to wait 4 months for an appointment) was being referred for counselling - that effectively became bereavement counselling as the situation was ultimately caused by being an executor of a relatives estate, and not spending time dealing with their death emotionally because I was too busy running around like a blue-arsed fly handling the will, legalities, funeral etc... part of those sessions dealt with spotting the signs of the attacks and training myself to deal with them. to be honest, I haven't really had a problem since... and I don't worry about it reoccurring, because I know if I sense it about to happen, then I can deal with it before it ever gets to the stage of real anxiety - certainly work and/or covid (unless I get it!) shouldn't trigger any issues on that anxiety front, and so the only stresses in my life are on issues that I can't control - so why waste my time worrying about them? I read in another thread that your stress is work/covid related - covid is going to be around in one form or another for the rest of the year at least (it might be another 6 months before I get both vaccine jabs), so you're going to have to find ways to deal with it... I mean, when I blacked out in the local shop in 2010, I just embarrassed myself... if something happens to you while you're driving, that's more serious with potential consequences for others. 🚑 you have to remember that if you've now reached the stage of having panic attacks, then it's unlikely to go away by itself - you need to address the root cause or at least release the stress valve a little... maybe that's talking to a doctor, or calling a helpline, friends/family etc... depends what options are available to you where you live. I wish you well. 🙂
    5 points
  33. I'll have to stop you right there, John. The same thing goes for regular clients. In theory, you could just change their details. It's just a hell lot easier to delete everything than to have hundreds of inactive users (all with unique email addresses). ... And so can a client. But - if the client wants their account deleted, we should (and must) delete it. If a user (not a client) actually decides to contact us and asks us to have their account removed, why shouldn't we be able to delete it? Sorry, but I just can't wrap my head around why a 'Delete User' button and/or API function has been made. Reasoning? We're forced to delete data about a client if the client requests it. Not doing so is punishable with huge fines. In 2018, WHMCS made a lot of steps to make it look like they cared about GDPR - and then they basically ruined it with a single update and can't understand why we feel something is wrong. Please, please, please, please (!!!!!) let us know why it has now taken 3 releases (I reported it before GA) and there's still no solution to this. It's really just a matter of deleting the user the same way that a client is deleted. Sorry about my tone in this reply, my it really frustrates me. You can't make a release that is so GDPR focused back in 2018 and then ruin it two years later saying: "You know, you can just manually edit out the personal information for each user" - WE COULD VERY WELL DO THAT WITH CLIENTS AS WELL BEFORE 2018, It's just a lot easier NOT having to do that.
    5 points
  34. WHMCS was one of the companies which take average 6 - 8 hours to respond to our support requests. Even if the answer requires canned responses. But recently since this month precisely, WHMCS support staffs impress me by sending their responses in less than five minutes. Read me, the last response I received from WHMCS staff about is just after one minute of my post. 👏 👏 👏 To all of their efforts.
    5 points
  35. 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.
    5 points
  36. I wouldn't argue with one word of that... the stuff about bug tracking is interesting - i've been here too long and have just got used to CORE-xxxxx being top secret for staff eyes only.... but taking a step back and thinking about other software bug tracking, yes it should be more accessible.... I found it far better years ago when submitting bugs was done here in the f0rum - you could actually see where the bugs are, and so try to work around them.... with BT being outside of here, then only the person submitting the bug, and WHMCS, know about it - until the next maintenance release and you can see the changelog... that's no way to do it.... at least using older releases, you know where the bugs are and that no new ones will be added - with latest versions, it's Russian roulette where the bugs are and if you're going to hit one. feature requests is a joke (and sadly not a funny one) - as you say, why have a nice community hall where we can all gather together, but when we want to make a suggestion, we need to go to the little shed at the bottom of the lane and make a note of it in there... it's ridiculous... you get users making feature requests... that nobody else knows have been created... so they then don't receive many votes... so they don't get implemented by WHMCS... and so the frustration builds.... on so many levels, WHMCS is a company that enjoys to shoot itself in the foot by its own actions. ... and if WHMCS development slowed down any more it would be going backwards - but I know what you meant.... less new features, but get them right before launch. openness applies to communication too... there's no harm in pre-warning us what's going to be in a beta before the code has been released... there might be a crap idea that we can nip in the bud before any coding time is wasted (e.g removing the domain pricing tables and then having to put them back a year later).... once they've released something as a beta, then it's a hell of a task to get a feature removed before general release... and once released, it's in there and then you're left to the feature request path to get it removed... (or apparently just have a few words with some WHMCS employees!). it's the general pervasive attitude of only WHMCS knows best that does my head in (e.g let's change how invoices are calculated and not even disucss it first), and the subsequence lack of communication - when was the last time they ever did a full survey of it's userbase and ask them what they want in the future releases (I can't ever recall one).... and i'm not counting the requests system in that, because that's a flawed broken system that needs ditching asap. v8 should be designed from a blank sheet of paper - because if it's just going to be a slight evolution from v7.6, then they might as well call it v7.7 and we can all go and find something else to use.
    5 points
  37. I'm sorry, but this is an asinine comment. I'm beyond worried that this is an official response from anyone at WHMCS. It's impossible to compare WHMCS to App Stores from significant companies that can generate MILLIONS of dollars. We're discussing themes and extensions for a PHP-based billing platform with finite market growth capabilities. Let's not patronize and alienate the developers that help make this platform usable. It's insulting. So you're telling me, @WHMCS John, that it would be such a resource bottleneck for WHMCS staff to spend time reviewing bot sign-ups and using basic investigation tactics to see that there is a problem? Hell, you could even wait for one of us to complain and take a look to see if it's legitimate. At this point, I would even accept some efforts to make it more difficult for bots to register and review products. Maybe require users to put in their WHMCS license key? Maybe have them associate it with their WHMCS client login? There has to be some form of bare minimum work here. I do love the comment about charging us to utilize the Marketplace. Some of us do not use WHMCS as a product and still have to pay a monthly charge to access the latest product updates. Would you be able to fix that? Ridiculous.
    4 points
  38. Targeted Security Releases have been published for our Current and Long Term Support versions (8.7 and 8.6) Owned License holders will be able to auto-update to 8.7.3 or 8.6.2, if your Support & Updates was active during those releases. We have also exceeded our Long Term Support policy by providing a patch for 8.5, because it recently reached End of Life. Users can apply if your Support & Updates was active during the 8.5 release. We do not recommend running an End of Life version of WHMCS for this reason. However on this occasion, if you're running an older End of Life version, please contact support and we can assist: https://www.whmcs.com/submit-a-ticket/
    4 points
  39. When displaying your payment options during the final stages of the checkout process, the available payment gateway options are shown as text – in a number of different ways based upon the order form template being used. If we wanted to make this more attractive, we could replace the text of any or all of the gateways, with an image or logo, by editing the viewcart.tpl template within the active order form template. In order to do this, we can use one of the WHMCS variables that we have access to during the checkout process - $gateway.sysname - the variable stores in lowercase, the unique name used by WHMCS for the payment gateway. This is not the value you entered for the gateway in the “Display Name” field in the “Payment Gateways” section of the Admin Area. The next step is to create or find images for each of the gateways that you wish to replace with a graphic, all in the same graphic format (PNG, JPG or GIF) and save them with a lowercase filename. For example, if you were using PNG format, then your “PayPal” image would be called ‘paypal.png’; your “Bank Transfer” image is called ‘banktransfer.png’; and the “Mail-In Payment” gateway (in the above example, named ‘Cheque’) would be ‘mailin.png’. I believe the filename to be used is based upon the filename of the gateway file in ‘modules/gateways’, but you should be able to find its value by viewing the source of your cart page in your browser... [<label><input type="radio" name="paymentmethod" value="paypal" onclick="hideCCForm()" /> <img src=images/paypal.png /> So the part of interest above is: value=”paypal”. You would then upload these images to your “images” directory within WHMCS. If you wanted to put them in their own folder within the “images” directory, you can – but you will need to adjust the URL in the code below to take account of the slightly different path (see end of tutorial). The images directory i'm using in these examples is whmcs/images - and not the template(s) images folder. The replacement code works by first creating a new variable to store the URL of the gateway logo, then it will check to see if the image exists in the “images” folder (remember that it must have a lowercase filename on the server otherwise it will not be found) – if the image exists, it will display the image; if no image is found, it will display the text (as it does now). In the examples above, I have only uploaded a ‘paypal’ logo and hence only that gateway is using a replacement image – if I were to upload logos for the other two gateways, they would also be used instead of their text names. So, I will now go through each of the eight existing order form templates and show the code to be replaced, the replacement code and an image of how the cart checkout page looks when the new code is added. Ajaxcart Replace.... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {$gateway.name}</label>{/foreach}</div> With... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</div> Boxes Replace.... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label> {/foreach}</p> With... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}</label> {/foreach}</p> Cart Replace... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label> {/foreach}</p> With... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</p> Comparison Replace... <p class="paymentmethods">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label><br />{/foreach}</p> With... <p class="paymentmethods">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label><br />{/foreach}</p> Modern Replace... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {$gateway.name}</label> {/foreach} With... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach} Slider Replace... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label> {/foreach} With... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach} Verticalsteps Replace... <p align="center">{foreach key=num item=gateway from=$gateways}<input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /><label for="pgbtn{$num}">{$gateway.name}</label> {/foreach}</p> With... <p align="center">{foreach key=num item=gateway from=$gateways}<input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /><label for="pgbtn{$num}">{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</p> Web20Cart Replace... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {$gateway.name}</label> {/foreach}</div> With... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</div> Customised Order Form Templates If you are using a customised order form, perhaps supplied with a purchased WHMCS theme, this solution may still work with your template - in viewcart.tpl, you simply replace... {$gateway.name} With... {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if} In these examples, I have used .PNG images - if you wanted to use .JPG or .GIF instead, then you would replace .png in the code with .jpg or .gif - remember, they must all use the same format! if you wanted to put the gateway images in their own folder, e.g 'paylogos', then you would replace the code... {assign var="paylogo" value="images/`$gateway.sysname`.png"} with... {assign var="paylogo" value="images/paylogos/`$gateway.sysname`.png"} I hope this helps anyone who wants to replace their payment gateways text with images. I should also add that this is tested and working on the latest WHMCS release as of this tutorial - v5.3.3
    4 points
  40. So WHMCS honors legacy reseller agreements, but they don't honor owned sold licenses? Amazing, really. I'm baffled.
    4 points
  41. No problem. I had a ticket reply earlier where it was noted. The eagerness of WHMCS support to get admin access and file level access concerns me. My client data is not worth risking for the sake of the support troubleshooting to identify a bug/issue.
    4 points
  42. it can be done... 🧙‍♂️ the OP has been given the working solution. 🎁
    4 points
  43. Who would prefer a opt in, or opt out option for the "value added" content that seems to be added whenever someone comes along with a golden handshake? With the recent inclusion of yet more 3rd rate party software creeping into the software we license. Is it becoming too annoying? I personally feel like it's becoming like logging into a minefield of spam - Litterally everywhere is a paid addon, within a piece of software I pay monthly for the ability to semi-automate a few tasks. Does anyone else feel it should be opt in, rather than "Gimme more $" at each click? Infact, do any of you guys use them and find it at all beneficial? If so which ones?
    4 points
  44. Not sure about you, but I did not agree to profit sharing. Someone having 10, 100, 5000, or a million clients does not mean WHMCS loses money because their costs do not go up when mine do. The only potential for costs on their side going up is support and if that is the case then they can simply limit the number of tickets per month or per year. Plenty of businesses that do software limit the number of tickets and I would prefer that over seat pricing any day. Seat pricing is needed in some cases, like where the demand is low for a product.
    4 points
  45. And they will reinvest that money into making Blesta a better product!
    4 points
  46. I posted the hook below previously in the v8 beta forums.... of course, the thread has got deleted.... when will i ever learn not to post code in the beta forums? <?php function admin_custom_css_hook($vars) { $head_return = '<style>.col-md-8 {width: 100% !important} .tasks {display: none;}</style>'; return $head_return; } add_hook("AdminAreaHeaderOutput",1,"admin_custom_css_hook");
    4 points
  47. Following a question from @Mauwiks... natively in WHMCS, there is no way to do this - but with the help of the attached hook, it is possible - just upload the hook to /includes/hooks the hook currently includes EIGHT different parameter options - I can think of at least 4 more options that I could add, and may do so at a later date, but I think 8 is plenty to be going on with. 🙂 note: the addon's ID value can be found when in the URL when you edit that product addon in the admin area - configaddons.php?action=manage&id=1 Linking to one specific product addon cart.php?gid=addons&id=1 Linking to Market Connect product addons by brand cart.php?gid=addons&id=codeguard cart.php?gid=addons&id=sitelock cart.php?gid=addons&id=spamexperts cart.php?gid=addons&id=ssl cart.php?gid=addons&id=weebly these addons are found by the hook searching whether specific terms are found at the START of the product addon descriptions, e.g Codeguard etc Linking to multiple product addons cart.php?gid=addons&multi[]=1&multi[]=32&multi[]=54 Linking to a predefined group of product addons cart.php?gid=addons&id=group1 $group1 is a predefined array of product addon IDs that you can edit in the hook.. $group1 = array(12,28,20); you could, in theory, have multiple groups (arrays of addon IDs) predefined in the hook, but it's currently only coded for 1 group - but it would be simple enough to change. if you pass a numeric addon ID value that doesn't exist for the particular client, then you'll get the no addons available error message... ... I did toy with the idea of showing all addons under those circumstances, but I decided against it for now - not least because it keeps the coding simplified! 😉 if you pass an undefined non-numeric id, e.g cart.php?gid=addons&id=brian, then there is nothing for the hook to remove and it will show all addons as per normal. you can only use one parameter option in a URL - e.g., you can't use cart.php?gid=addons&id=43&multi[]=32 addons_mauwiks.php
    4 points
  48. do you think the timing of launching a beta testing period one week before Christmas might have had something to do with that? 🙄
    4 points
×
×
  • 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