-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathclientarea.php
More file actions
2445 lines (2443 loc) · 134 KB
/
clientarea.php
File metadata and controls
2445 lines (2443 loc) · 134 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/*
* @ https://EasyToYou.eu - IonCube v11 Decoder Online
* @ PHP 7.2 & 7.3
* @ Decoder version: 1.1.6
* @ Release: 10/08/2022
*/
// Decoded file for php version 72.
define("CLIENTAREA", true);
require __DIR__ . "/init.php";
require_once ROOTDIR . "/includes/clientfunctions.php";
require_once ROOTDIR . "/includes/gatewayfunctions.php";
require_once ROOTDIR . "/includes/ccfunctions.php";
require_once ROOTDIR . "/includes/domainfunctions.php";
require_once ROOTDIR . "/includes/registrarfunctions.php";
require_once ROOTDIR . "/includes/customfieldfunctions.php";
require_once ROOTDIR . "/includes/invoicefunctions.php";
require_once ROOTDIR . "/includes/configoptionsfunctions.php";
Auth::requireLoginAndClient(true);
$action = $whmcs->get_req_var("action");
$sub = $whmcs->get_req_var("sub");
$id = (int) $whmcs->get_req_var("id");
$modop = $whmcs->get_req_var("modop");
$submit = $whmcs->get_req_var("submit");
$save = $whmcs->get_req_var("save");
$q = $whmcs->get_req_var("q");
$userid = App::getFromRequest("userid");
$paymentmethod = WHMCS\Gateways::makeSafeName($whmcs->get_req_var("paymentmethod"));
$params = [];
$addRenewalToCart = $whmcs->get_req_var("addRenewalToCart");
$today = WHMCS\Carbon::today();
if($addRenewalToCart) {
check_token();
$renewID = $whmcs->get_req_var("renewID");
$renewalPeriod = $whmcs->get_req_var("period");
WHMCS\OrderForm::addDomainRenewalToCart($renewID, $renewalPeriod);
WHMCS\Terminus::getInstance()->doExit();
} elseif($action == "parseMarkdown") {
check_token();
$markup = new WHMCS\View\Markup\Markup();
echo json_encode(["body" => $markup->transform($whmcs->get_req_var("content"), "markdown")]);
WHMCS\Terminus::getInstance()->doExit();
} elseif($action === "installWordpress") {
check_token();
$serviceId = (int) App::getFromRequest("serviceId");
$service = WHMCS\Service\Service::find($serviceId);
$productModuleActionSettings = json_decode($service->product->getModuleConfigurationSetting("moduleActions")->value, true) ?? [];
if(empty($productModuleActionSettings["InstallWordPress"]["client"])) {
echo json_encode(["error" => "Access Denied"]);
WHMCS\Terminus::getInstance()->doExit();
}
if(!$service || $service->clientId !== Auth::client()->id) {
echo json_encode(["status" => false, "error" => "Access Denied"]);
WHMCS\Terminus::getInstance()->doExit();
}
$server = new WHMCS\Module\Server();
$server->loadByServiceID($serviceId);
$response = $server->call("InstallWordPress", ["blog_title" => App::getFromRequest("blog_title"), "blog_path" => App::getFromRequest("path"), "admin_pass" => App::getFromRequest("admin_pass")]);
if(empty($response["error"])) {
$jsonResponse = ["status" => true, "blogTitle" => $response["site-title"], "instanceUrl" => $response["protocol"] . "://" . $response["domain"] . "/" . $response["path"], "path" => rtrim("/" . $response["path"], "/")];
} else {
$jsonResponse["error"] = $response["error"];
}
echo json_encode($jsonResponse);
WHMCS\Terminus::getInstance()->doExit();
} elseif($action == "manage-service") {
check_token();
$serviceId = App::getFromRequest("service-id");
$sub = App::getFromRequest("sub");
$server = new WHMCS\Module\Server();
if(substr($serviceId, 0, 1) == "a") {
$server->loadByAddonId((int) substr($serviceId, 1));
$errorPrependText = "An error occurred when managing Service Addon ID: " . (int) substr($serviceId, 1) . ": ";
} else {
$serviceId = (int) $serviceId;
$server->loadByServiceID($serviceId);
$errorPrependText = "An error occurred when managing Service ID: " . $serviceId . ": ";
}
$serviceServerParams = $server->buildParams();
$allowedModuleFunctions = [];
$clientAreaAllowedFunctions = $server->call("ClientAreaAllowedFunctions");
if(is_array($clientAreaAllowedFunctions) && !array_key_exists("error", $clientAreaAllowedFunctions)) {
foreach ($clientAreaAllowedFunctions as $functionName) {
if(is_string($functionName)) {
$allowedModuleFunctions[] = $functionName;
}
}
}
$clientAreaCustomButtons = $server->call("ClientAreaCustomButtonArray");
if(is_array($clientAreaCustomButtons) && !array_key_exists("error", $clientAreaAllowedFunctions)) {
foreach ($clientAreaCustomButtons as $buttonLabel => $functionName) {
if(is_string($functionName)) {
$allowedModuleFunctions[] = $functionName;
}
}
}
$response = ["error" => "An unknown error occurred"];
if(Auth::client()->id == $serviceServerParams["userid"]) {
if(in_array("manage_order", $allowedModuleFunctions) && $server->functionExists("manage_order") && $sub !== "manage") {
if(!checkContactPermission("productsso", true)) {
$response = ["error" => Lang::trans("subaccountSsoDenied")];
} else {
$apiResponse = $server->call("manage_order");
if(is_array($apiResponse) && isset($apiResponse["jsonResponse"])) {
$apiResponse = $apiResponse["jsonResponse"];
if(!empty($apiResponse["success"]) && isset($apiResponse["redirect"])) {
$response = ["redirect" => $apiResponse["redirect"]];
} elseif(isset($apiResponse["error"])) {
$response = ["error" => $apiResponse["error"]];
}
}
unset($apiResponse);
}
} elseif($sub === "manage") {
if(!empty($serviceServerParams["addonId"])) {
App::redirectToRoutePath("module-custom-action-addon", [$serviceServerParams["serviceid"], $serviceServerParams["addonId"], "manage"]);
} else {
App::redirectToRoutePath("module-custom-action", [$serviceServerParams["serviceid"], "manage"]);
}
} else {
$response = ["error" => "Function Not Allowed"];
}
} else {
$response = ["error" => "Access Denied"];
}
echo json_encode($response);
WHMCS\Terminus::getInstance()->doExit();
}
$activeLanguage = WHMCS\Session::get("Language");
if($action == "changesq" || $whmcs->get_req_var("2fasetup")) {
$action = "security";
}
$ca = new WHMCS\ClientArea();
$ca->setPageTitle($whmcs->get_lang("clientareatitle"));
$ca->addToBreadCrumb("index.php", $whmcs->get_lang("globalsystemname"))->addToBreadCrumb("clientarea.php", $whmcs->get_lang("clientareatitle"));
$ca->initPage();
$ca->requireLogin();
$legacyClient = new WHMCS\Client($ca->getClient());
if($action == "hosting") {
$ca->addToBreadCrumb("clientarea.php?action=hosting", $whmcs->get_lang("clientareanavhosting"));
}
if(in_array($action, ["products", "services", "cancel"])) {
$ca->addToBreadCrumb("clientarea.php?action=products", $whmcs->get_lang("clientareaproducts"));
}
if(in_array($action, ["domains", "domaindetails", "domaincontacts", "domaindns", "domainemailforwarding", "domaingetepp", "domainregisterns", "domainaddons"])) {
$ca->addToBreadCrumb("clientarea.php?action=domains", $whmcs->get_lang("clientareanavdomains"));
}
if($action == "invoices") {
$ca->addToBreadCrumb("clientarea.php?action=invoices", $whmcs->get_lang("invoices"));
}
if($action == "emails") {
$ca->addToBreadCrumb("clientarea.php?action=emails", $whmcs->get_lang("clientareaemails"));
}
if($action == "addfunds") {
$ca->addToBreadCrumb("clientarea.php?action=addfunds", $whmcs->get_lang("addfunds"));
}
if($action == "masspay") {
$ca->addToBreadCrumb("clientarea.php?action=masspay" . ($whmcs->get_req_var("all") ? "&all=true" : "") . "#", $whmcs->get_lang("masspaytitle"));
}
if($action == "quotes") {
$ca->addToBreadCrumb("clientarea.php?action=quotes", $whmcs->get_lang("quotestitle"));
}
$currency = WHMCS\Billing\Currency::factoryForClientArea();
if(substr($action, 0, 6) == "domain" && $action != "domains") {
$domainID = $whmcs->get_req_var("id");
if(!$domainID) {
$domainID = $whmcs->get_req_var("domainid");
}
$domains = new WHMCS\Domains();
$domainData = $domains->getDomainsDatabyID($domainID);
if(!$domainData) {
redir("action=domains", "clientarea.php");
}
$domainModel = WHMCS\Domain\Domain::find($domainData["id"]);
$ca->setDisplayTitle(Lang::trans("managing") . " " . $domainData["domain"]);
$domainName = new WHMCS\Domains\Domain($domainData["domain"]);
$managementOptions = $domains->getManagementOptions();
try {
$registrar = $domainModel->getRegistrarInterface();
$params = $registrar->getSettings();
} catch (Exception $e) {
$registrar = NULL;
$params = [];
}
$ca->assign("managementoptions", $managementOptions);
}
$ca->assign("action", $action);
$ca->assign("clientareaaction", $action);
if($action == "") {
$templateVars = $ca->getTemplateVariables();
$ca->setDisplayTitle(Lang::trans("welcomeback") . ", " . Auth::user()->firstName);
$ca->setTemplate("clientareahome");
if(App::getFromRequest("inviteaccepted")) {
WHMCS\FlashMessages::add(Lang::trans("accountInvite.acceptSuccess"), "success");
}
$clientId = $ca->getClient()->id;
$panels = [];
$sitejetServices = $ca->getClient()->services()->whereIn("domainstatus", ["Active", "Suspended"])->orderBy("domainstatus", "asc")->orderBy("id", "desc")->limit(20)->get()->filter(function (WHMCS\Service\Service $service) {
return WHMCS\Service\Adapters\SitejetAdapter::factory($service)->isSitejetActive();
});
if(0 < $sitejetServices->count()) {
$bodyHtml = $ca->getSingleTPLOutput("includes/sitejet/homepagepanel", ["sitejetServices" => $sitejetServices]);
$panels[] = ["name" => "Sitejet Builder", "label" => Lang::trans("sitejetBuilder.dashboardPanelTitle"), "icon" => "fas fa-tv", "attributes" => ["id" => "sitejetPromoPanel"], "extras" => ["color" => "blue", "colspan" => true], "bodyHtml" => $bodyHtml, "order" => "1"];
}
if(checkContactPermission("invoices", true)) {
$invoiceTypeItemInvoiceIds = WHMCS\Database\Capsule::table("tblinvoiceitems")->where("userid", $userid)->where("type", "Invoice")->pluck("invoiceid")->all();
$invoices = WHMCS\Database\Capsule::table("tblinvoices")->where("tblinvoices.userid", $clientId)->where("status", "Unpaid")->where("duedate", "<", WHMCS\Carbon::now()->toDateString())->whereNotIn("tblinvoices.id", $invoiceTypeItemInvoiceIds)->leftJoin("tblaccounts", "tblaccounts.invoiceid", "=", "tblinvoices.id")->groupBy("tblinvoices.id")->get([WHMCS\Database\Capsule::raw("IFNULL(total, 0) as total"), WHMCS\Database\Capsule::raw("IFNULL(SUM(amountin), 0) as amount_in"), WHMCS\Database\Capsule::raw("IFNULL(SUM(amountout), 0) as amount_out")])->all();
$invoiceCount = count($invoices);
if($invoiceCount) {
$invoices = collect($invoices);
$msg = Lang::trans("clientHomePanels.overdueInvoicesMsg", [":numberOfInvoices" => $invoiceCount, ":balanceDue" => formatCurrency($invoices->sum(function ($invoice) {
return $invoice->total - $invoice->amount_in + $invoice->amount_out;
}))]);
$panels[] = ["name" => "Overdue Invoices", "label" => Lang::trans("clientHomePanels.overdueInvoices"), "icon" => "fa-calculator", "attributes" => ["id" => "overdueInvoicesPanel"], "extras" => ["color" => "red", "btn-icon" => "fas fa-arrow-right", "btn-link" => "clientarea.php?action=masspay&all=true", "btn-text" => Lang::trans("invoicespaynow")], "bodyHtml" => "<p>" . $msg . "</p>", "order" => "10"];
} else {
$invoices = WHMCS\Database\Capsule::table("tblinvoices")->where("tblinvoices.userid", $clientId)->where("status", "Unpaid")->whereNotIn("tblinvoices.id", $invoiceTypeItemInvoiceIds)->leftJoin("tblaccounts", "tblaccounts.invoiceid", "=", "tblinvoices.id")->groupBy("tblinvoices.id")->get([WHMCS\Database\Capsule::raw("IFNULL(SUM(DISTINCT total), 0) as total"), WHMCS\Database\Capsule::raw("IFNULL(SUM(amountin), 0) as amount_in"), WHMCS\Database\Capsule::raw("IFNULL(SUM(amountout), 0) as amount_out")])->all();
$invoiceCount = count($invoices);
if($invoiceCount) {
$invoices = collect($invoices);
$msg = Lang::trans("clientHomePanels.unpaidInvoicesMsg", [":numberOfInvoices" => $invoiceCount, ":balanceDue" => formatCurrency($invoices->sum(function ($invoice) {
return $invoice->total - $invoice->amount_in + $invoice->amount_out;
}))]);
$panels[] = ["name" => "Unpaid Invoices", "label" => Lang::trans("clientHomePanels.unpaidInvoices"), "icon" => "fa-calculator", "attributes" => ["id" => "unpaidInvoicesPanel"], "extras" => ["color" => "red", "btn-icon" => "fas fa-arrow-right", "btn-link" => "clientarea.php?action=invoices", "btn-text" => Lang::trans("viewAll")], "bodyHtml" => "<p>" . $msg . "</p>", "order" => "10"];
}
}
}
if(checkContactPermission("domains", true)) {
$domainsDueWithin45Days = $ca->getClient()->domains()->nextDueBefore(WHMCS\Carbon::now()->addDays(45))->notFree()->count();
if(0 < $domainsDueWithin45Days) {
$msg = Lang::trans("clientHomePanels.domainsExpiringSoonMsg", [":days" => 45, ":numberOfDomains" => $domainsDueWithin45Days]);
$extras = [];
if(WHMCS\Config\Setting::getValue("EnableDomainRenewalOrders")) {
$extras = ["btn-icon" => "fas fa-sync", "btn-link" => routePath("cart-domain-renewals"), "btn-text" => Lang::trans("domainsrenewnow")];
}
$extras["color"] = "midnight-blue";
$panels[] = ["name" => "Domains Expiring Soon", "label" => Lang::trans("clientHomePanels.domainsExpiringSoon"), "icon" => "fa-globe", "attributes" => ["id" => "expiringDomainsPanel"], "extras" => $extras, "bodyHtml" => "<p>" . $msg . "</p>", "order" => "50"];
}
}
if(checkContactPermission("products", true)) {
$servicesList = [];
$services = $ca->getClient()->services()->whereIn("domainstatus", ["Active", "Suspended"])->orderBy("domainstatus", "asc")->orderBy("id", "desc")->limit(101)->get();
$statusProperties = [WHMCS\Service\Status::ACTIVE => ["icon" => "fa-check-circle", "modifier" => "success", "translation" => Lang::trans("clientareaactive")], WHMCS\Service\Status::SUSPENDED => ["icon" => "fa-exclamation-triangle", "modifier" => "warning", "translation" => Lang::trans("clientareasuspended")]];
uasort($statusProperties, function ($a, $b) {
return strlen($a["translation"]) < strlen($b["translation"]);
});
foreach ($services as $service) {
$buttonData = $service->getCustomActionData();
$isolatedServiceButtons = array_filter($buttonData, function ($btn) {
return $btn["prefersIsolation"];
});
$groupedServiceButtons = array_filter($buttonData, function ($btn) {
return !$btn["prefersIsolation"];
});
$label = $ca->getSingleTPLOutput("includes/active-products-services-item", ["ca" => $ca, "buttonData" => $buttonData, "primaryServiceBtn" => array_shift($groupedServiceButtons), "secondaryButtons" => $groupedServiceButtons, "accentPrimaryServiceBtns" => $isolatedServiceButtons, "service" => $service, "statusProperties" => $statusProperties]);
$servicesList[] = ["label" => $label];
}
$servicesPanel = ["name" => "Active Products/Services", "label" => Lang::trans("clientHomePanels.activeProductsServices"), "icon" => "fa-cube", "attributes" => ["id" => "servicesPanel"], "extras" => ["color" => "gold", "btn-icon" => "fas fa-arrow-right", "btn-link" => "clientarea.php?action=services", "btn-text" => Lang::trans("clientareanavservices"), "colspan" => true], "footerHtml" => "<a href=\"#\" class=\"btn-view-more pull-right float-right" . (4 < $services->count() ? "\">" : " disabled\" aria-disabled=\"true\">") . Lang::trans("viewMore") . "</a><div class=\"clearfix\"></div>", "children" => $servicesList, "order" => "100"];
$bodyHtml = "";
if(count($servicesList) == 0) {
$bodyHtml .= "<p>" . Lang::trans("clientHomePanels.activeProductsServicesNone") . "</p>";
} elseif(100 < count($servicesList)) {
unset($servicesPanel["children"][100]);
$bodyHtml .= "<p>" . Lang::trans("clientHomePanels.showingRecent100") . ".</p>";
}
if($bodyHtml) {
$servicesPanel["bodyHtml"] = $bodyHtml;
}
$panels[] = $servicesPanel;
$servicesRenewingSoonCount = $ca->getClient()->getEligibleOnDemandRenewalServices()->count() + $ca->getClient()->getEligibleOnDemandRenewalServiceAddons()->count();
if(0 < $servicesRenewingSoonCount) {
$extras = ["color" => "midnight-blue", "btn-icon" => "fas fa-sync", "btn-link" => routePath("service-renewals"), "btn-text" => Lang::trans("domainsrenewnow")];
$serviceRenewingSoonMsg = Lang::trans("clientHomePanels.serviceRenewingSoonMsg", [":numberOfServices" => $servicesRenewingSoonCount]);
$panels[] = ["name" => "Services Renewing Soon", "label" => Lang::trans("clientHomePanels.serviceRenewingSoon"), "icon" => "fa-cube", "attributes" => ["id" => "renewingServicesPanel"], "extras" => $extras, "bodyHtml" => "<p>" . $serviceRenewingSoonMsg . "</p>", "order" => "50"];
}
}
if(checkContactPermission("orders", true) && (WHMCS\Config\Setting::getValue("AllowRegister") || WHMCS\Config\Setting::getValue("AllowTransfer"))) {
$bodyContent = "<form method=\"post\" action=\"domainchecker.php\">\n <div class=\"input-group margin-10 m-0 px-2 pb-2\">\n <input type=\"text\" name=\"domain\" class=\"form-control\" />\n <div class=\"input-group-btn input-group-append\">";
if(WHMCS\Config\Setting::getValue("AllowRegister")) {
$bodyContent .= "\n <input type=\"submit\" value=\"" . Lang::trans("domainsregister") . "\" class=\"btn btn-success\" />";
}
if(WHMCS\Config\Setting::getValue("AllowTransfer")) {
$bodyContent .= "\n <input type=\"submit\" name=\"transfer\" value=\"" . Lang::trans("domainstransfer") . "\" class=\"btn btn-default\" />";
}
$bodyContent .= "\n </div>\n </div>\n </form>";
$panels[] = ["name" => "Register a New Domain", "label" => Lang::trans("navregisterdomain"), "icon" => "fa-globe", "attributes" => ["id" => "registerDomainPanel"], "extras" => ["color" => "emerald"], "bodyHtml" => $bodyContent, "order" => "200"];
}
if(WHMCS\Config\Setting::getValue("AffiliateEnabled") && checkContactPermission("affiliates", true) && !is_null($affiliate = $ca->getClient()->affiliate)) {
$currencyLimit = convertCurrency(WHMCS\Config\Setting::getValue("AffiliatePayout"), 1, $currency["id"]);
$amountUntilWithdrawal = $currencyLimit - $affiliate->balance;
if(0 < $amountUntilWithdrawal) {
$msgTemplate = "clientHomePanels.affiliateSummary";
} else {
$msgTemplate = "clientHomePanels.affiliateSummaryWithdrawalReady";
}
$msg = Lang::trans($msgTemplate, [":commissionBalance" => formatCurrency($affiliate->balance), ":amountUntilWithdrawalLevel" => formatCurrency($amountUntilWithdrawal)]);
$panels[] = ["name" => "Affiliate Program", "label" => Lang::trans("clientHomePanels.affiliateProgram"), "icon" => "fa-users", "attributes" => ["id" => "affiliatesPanel"], "extras" => ["color" => "teal", "btn-icon" => "fas fa-arrow-right", "btn-link" => "affiliates.php", "btn-text" => Lang::trans("moreDetails")], "bodyHtml" => "<p>" . $msg . "</p>", "order" => "300"];
}
if(!function_exists("AddNote")) {
require ROOTDIR . DIRECTORY_SEPARATOR . "includes" . DIRECTORY_SEPARATOR . "ticketfunctions.php";
}
$tickets = [];
$statusfilter = [];
$result = select_query("tblticketstatuses", "title", ["showactive" => "1"]);
while ($data = mysql_fetch_array($result)) {
$statusfilter[] = $data[0];
}
$result = select_query("tbltickets", "", ["userid" => (int) $legacyClient->getID(), "status" => ["sqltype" => "IN", "values" => $statusfilter], "merged_ticket_id" => 0], "lastreply", "DESC");
while ($data = mysql_fetch_array($result)) {
$id = $data["id"];
$tid = $data["tid"];
$c = $data["c"];
$deptid = $data["did"];
$date = $data["date"];
$date = fromMySQLDate($date, 1, 1);
$subject = $data["title"];
$status = $data["status"];
$urgency = $data["urgency"];
$lastreply = $data["lastreply"];
$lastreply = fromMySQLDate($lastreply, 1, 1);
$clientunread = $data["clientunread"];
$htmlFormattedStatus = getStatusColour($status);
$dept = getDepartmentName($deptid);
$urgency = Lang::trans("supportticketsticketurgency" . strtolower($urgency));
$statusClass = WHMCS\View\Helper::generateCssFriendlyClassName($status);
$tickets[] = ["id" => $id, "tid" => $tid, "c" => $c, "date" => $date, "department" => $dept, "subject" => $subject, "status" => $htmlFormattedStatus, "statusClass" => $statusClass, "urgency" => $urgency, "lastreply" => $lastreply, "unread" => $clientunread];
}
$ca->assign("tickets", $tickets);
if(checkContactPermission("tickets", true)) {
$ticketsList = [];
$rawStatusColors = WHMCS\Database\Capsule::table("tblticketstatuses")->get()->all();
$ticketRows = WHMCS\Database\Capsule::table("tbltickets")->where("userid", "=", $legacyClient->getID())->where("merged_ticket_id", "=", "0")->orderBy("lastreply", "DESC")->limit(10)->get()->all();
foreach ($ticketRows as $data) {
$id = $data->id;
$tid = $data->tid;
$c = $data->c;
$subject = $data->title;
$status = $data->status;
$lastreply = $data->lastreply;
$clientunread = $data->clientunread;
$lastreply = fromMySQLDate($lastreply, 1, 1);
$statusColors = [];
foreach ($rawStatusColors as $color) {
$statusColors[$color->title] = $color->color;
}
$langStatus = preg_replace("/[^a-z]/i", "", strtolower($status));
if(Lang::trans("supportticketsstatus" . $langStatus) != "supportticketsstatus" . $langStatus) {
$statusText = Lang::trans("supportticketsstatus" . $langStatus);
} else {
$statusText = $status;
}
$ticketsList[] = ["uri" => "viewticket.php?tid=" . $tid . "&c=" . $c, "label" => ($clientunread ? "<strong>" : "") . "#" . $tid . " - " . $subject . ($clientunread ? "</strong> " : " ") . "<label class=\"label\" style=\"background-color: " . $statusColors[$status] . "\">" . $statusText . "</label><br />" . "<small>" . Lang::trans("supportticketsticketlastupdated") . ": " . $lastreply . "</small>"];
}
$ticketsPanel = ["name" => "Recent Support Tickets", "label" => Lang::trans("clientHomePanels.recentSupportTickets"), "icon" => "fa-comments", "attributes" => ["id" => "ticketsPanel"], "extras" => ["color" => "blue", "btn-icon" => "fas fa-plus", "btn-link" => "submitticket.php", "btn-text" => Lang::trans("opennewticket")], "children" => $ticketsList, "order" => "150"];
if(count($ticketsList) == 0) {
$ticketsPanel["bodyHtml"] = "<p>" . Lang::trans("clientHomePanels.recentSupportTicketsNone") . "</p>";
}
$panels[] = $ticketsPanel;
}
$files = $legacyClient->getFiles();
if(0 < count($files)) {
$filesList = [];
foreach ($files as $file) {
$filesList[] = ["label" => $file["title"] . "<br /><small>" . $file["date"] . "</small>", "uri" => "dl.php?type=f&id=" . $file["id"]];
}
$panels[] = ["name" => "Your Files", "label" => Lang::trans("clientareafiles"), "icon" => "fa-download", "attributes" => ["id" => "filesPanel"], "extras" => ["color" => "purple"], "children" => $filesList, "order" => "250"];
}
$announcementsList = [];
$announcements = WHMCS\Announcement\Announcement::wherePublished(true)->orderBy("date", "DESC")->take(3)->get();
foreach ($announcements as $announcement) {
$announcementTitle = $announcement->title;
$announcementContent = $announcement->announcement;
if($activeLanguage) {
try {
$announcementLocal = WHMCS\Announcement\Announcement::whereParentid($announcement->id)->whereLanguage($activeLanguage)->firstOrFail();
$announcementTitle = $announcementLocal->title;
$announcementContent = $announcementLocal->announcement;
} catch (Illuminate\Database\Eloquent\ModelNotFoundException $e) {
}
}
$uri = getModRewriteFriendlyString($announcementTitle);
$announcementsList[] = ["id" => $announcement->id, "date" => fromMySQLDate($announcement->date, 0, 1), "title" => $announcementTitle, "urlfriendlytitle" => $uri, "text" => $announcementContent, "label" => $announcementTitle . "<br /><span class=\"text-last-updated\">" . fromMySQLDate($announcement->publishDate, 0, 1) . "</span>", "uri" => routePath("announcement-view", $announcement->id, $uri)];
}
$smartyvalues["announcements"] = $announcementsList;
$panels[] = ["name" => "Recent News", "label" => Lang::trans("clientHomePanels.recentNews"), "icon" => "far fa-newspaper", "attributes" => ["id" => "announcementsPanel"], "extras" => ["color" => "asbestos", "btn-icon" => "fas fa-arrow-right", "btn-link" => routePath("announcement-index"), "btn-text" => Lang::trans("viewAll")], "children" => $announcementsList, "order" => "500"];
$smartyvalues["registerdomainenabled"] = (bool) WHMCS\Config\Setting::getValue("AllowRegister");
$smartyvalues["transferdomainenabled"] = (bool) WHMCS\Config\Setting::getValue("AllowTransfer");
$smartyvalues["owndomainenabled"] = (bool) WHMCS\Config\Setting::getValue("AllowOwnDomain");
$captcha = new WHMCS\Utility\Captcha();
$smartyvalues["captcha"] = $captcha;
$smartyvalues["captchaForm"] = WHMCS\Utility\Captcha::FORM_REGISTRATION;
$smartyvalues["contacts"] = $legacyClient->getContacts();
$addons_html = run_hook("ClientAreaHomepage", []);
$ca->assign("addons_html", $addons_html);
$factory = new WHMCS\View\Menu\MenuFactory();
$item = $factory->getLoader()->load(["name" => "ClientAreaHomePagePanels", "children" => $panels]);
run_hook("ClientAreaHomepagePanels", [$item], true);
$smartyvalues["panels"] = WHMCS\View\Menu\Item::sort($item);
$ca->addOutputHookFunction("ClientAreaPageHome");
} elseif($action == "details") {
checkContactPermission("profile");
$ca->setDisplayTitle(Lang::trans("clientareanavdetails"));
$ca->setTemplate("clientareadetails");
$ca->addToBreadCrumb("clientarea.php?action=details", Lang::trans("clientareanavdetails"));
$optionalFields = explode(",", WHMCS\Config\Setting::getValue("ClientsProfileOptionalFields"));
$uneditablefields = explode(",", WHMCS\Config\Setting::getValue("ClientsProfileUneditableFields"));
$smartyvalues["optionalFields"] = $optionalFields;
$smartyvalues["uneditablefields"] = $uneditablefields;
$e = "";
$exdetails = [];
$ca->assign("successful", false);
if($save) {
check_token();
$emailFlags = CHECKDETAILS_EMAIL_ALL ^ CHECKDETAILS_EMAIL_UNIQUE_USER;
if(in_array("email", $uneditablefields)) {
$emailFlags = CHECKDETAILS_EMAIL_NONE;
} elseif(App::getFromRequest("email") === $legacyClient->getDetails()["email"]) {
$emailFlags ^= CHECKDETAILS_EMAIL_BANNED_DOMAIN;
}
$e = checkDetailsareValid($legacyClient->getID(), false, $emailFlags);
unset($emailFlags);
if($e) {
$ca->assign("errormessage", $e);
} else {
$legacyClient->updateClient();
redir("action=details&success=1");
}
}
if($whmcs->get_req_var("success")) {
$ca->assign("successful", true);
}
$exdetails = $legacyClient->getDetails();
$countries = new WHMCS\Utility\Country();
$ca->assign("clientfirstname", $whmcs->get_req_var_if($e, "firstname", $exdetails));
$ca->assign("clientlastname", $whmcs->get_req_var_if($e, "lastname", $exdetails));
$ca->assign("clientcompanyname", $whmcs->get_req_var_if($e, "companyname", $exdetails));
$ca->assign("clientemail", $whmcs->get_req_var_if($e, "email", $exdetails));
$ca->assign("clientaddress1", $whmcs->get_req_var_if($e, "address1", $exdetails));
$ca->assign("clientaddress2", $whmcs->get_req_var_if($e, "address2", $exdetails));
$ca->assign("clientcity", $whmcs->get_req_var_if($e, "city", $exdetails));
$ca->assign("clientstate", $whmcs->get_req_var_if($e, "state", $exdetails));
$ca->assign("clientpostcode", $whmcs->get_req_var_if($e, "postcode", $exdetails));
$ca->assign("clientcountry", $countries->getName($whmcs->get_req_var_if($e, "country", $exdetails)));
$ca->assign("clientcountriesdropdown", getCountriesDropDown($whmcs->get_req_var_if($e, "country", $exdetails), "", "", false, in_array("country", $uneditablefields)));
$phoneNumber = $e ? App::formatPostedPhoneNumber() : $exdetails["telephoneNumber"];
$ca->assign("clientphonenumber", $phoneNumber);
$ca->assign("clientTaxId", $whmcs->get_req_var_if($e, "tax_id", $exdetails));
$ca->assign("customfields", getCustomFields("client", "", $legacyClient->getID(), "", "", $whmcs->get_req_var("customfield")));
$ca->assign("contacts", $legacyClient->getContacts());
$ca->assign("billingcid", $whmcs->get_req_var_if($e, "billingcid", $exdetails));
$ca->assign("paymentmethods", showPaymentGatewaysList([], $legacyClient->getID()));
$ca->assign("taxIdLabel", WHMCS\Billing\Tax\Vat::getLabel());
$ca->assign("showTaxIdField", WHMCS\Billing\Tax\Vat::isUsingNativeField());
$ca->assign("showMarketingEmailOptIn", WHMCS\Config\Setting::getValue("AllowClientsEmailOptOut"));
$ca->assign("marketingEmailOptInMessage", Lang::trans("emailMarketing.optInMessage") != "emailMarketing.optInMessage" ? Lang::trans("emailMarketing.optInMessage") : WHMCS\Config\Setting::getValue("EmailMarketingOptInMessage"));
$ca->assign("marketingEmailOptIn", App::isInRequest("marketingoptin") ? (bool) App::getFromRequest("marketingoptin") : $legacyClient->getClientModel()->isOptedInToMarketingEmails());
$ca->assign("defaultpaymentmethod", $whmcs->get_req_var_if($e, "paymentmethod", $exdetails, "defaultgateway"));
$emailPreferences = [];
foreach (WHMCS\Mail\Emailer::CLIENT_EMAILS as $emailType) {
$emailPreferences[$emailType] = App::get_req_var_if($e, "email_preferences", $exdetails, "", $emailType);
}
$ca->assign("emailPreferencesEnabled", !WHMCS\Config\Setting::getValue("DisableClientEmailPreferences"));
$ca->assign("emailPreferences", $emailPreferences);
$ca->assign("clientLanguage", $exdetails["language"]);
$ca->assign("languages", WHMCS\Language\ClientLanguage::getLanguages());
foreach ($uneditablefields as $field) {
$ca->assign("client" . $field, $exdetails[$field] ?? NULL, true);
}
$ca->addOutputHookFunction("ClientAreaPageProfile");
} elseif($action == "contacts") {
App::redirectToRoutePath("account-contacts", [], ["contactid" => App::getFromRequest("id")]);
} elseif($action == "addcontact") {
App::redirectToRoutePath("account-contacts");
} elseif($action == "creditcard") {
App::redirectToRoutePath("account-paymentmethods");
} elseif($action == "changepw") {
App::redirectToRoutePath("user-password");
} elseif($action == "security") {
if(!Auth::hasPermission("profile")) {
App::redirectToRoutePath("user-permission-denied");
}
$ca->setDisplayTitle(Lang::trans("navAccountSecurity"));
$ca->setTemplate("clientareasecurity");
$ca->addToBreadCrumb("clientarea.php?action=details", $whmcs->get_lang("clientareanavdetails"));
$ca->addToBreadCrumb("clientarea.php?action=security", $whmcs->get_lang("navAccountSecurity"));
if($whmcs->get_req_var("toggle_sso")) {
check_token();
$client = $ca->getClient();
$client->allowSso = (bool) $whmcs->get_req_var("allow_sso");
$client->save();
exit;
}
$smartyvalues["showSsoSetting"] = 1 <= WHMCS\ApplicationLink\ApplicationLink::whereIsEnabled(1)->count();
$smartyvalues["isSsoEnabled"] = $ca->getClient()->allowSso;
$ca->addOutputHookFunction("ClientAreaPageSecurity");
} elseif(in_array($action, ["hosting", "products", "services"])) {
checkContactPermission("products");
$ca->setDisplayTitle(Lang::trans("clientareaproducts"));
$ca->setTemplate("clientareaproducts");
$table = "tblhosting";
$fields = "COUNT(*)";
$where = "userid='" . db_escape_string($legacyClient->getID()) . "'";
if($q) {
$q = preg_replace("/[^a-z0-9-.]/", "", strtolower($q));
$where .= " AND domain LIKE '%" . db_escape_string($q) . "%'";
$smartyvalues["q"] = $q;
}
if($module = $whmcs->get_req_var("module")) {
$where .= " AND tblproducts.servertype='" . db_escape_string($module) . "'";
}
$innerjoin = "tblproducts ON tblproducts.id=tblhosting.packageid INNER JOIN tblproductgroups ON tblproductgroups.id=tblproducts.gid";
$result = select_query($table, $fields, $where, "", "", "", $innerjoin);
$data = mysql_fetch_array($result);
$numitems = $data[0];
list($orderby, $sort, $limit) = clientAreaTableInit("prod", "product", "ASC", $numitems);
$smartyvalues["orderby"] = $orderby;
$smartyvalues["sort"] = strtolower($sort);
if($orderby == "price") {
$orderby = "amount";
} elseif($orderby == "billingcycle") {
$orderby = "billingcycle";
} elseif($orderby == "nextduedate") {
$orderby = "nextduedate";
} elseif($orderby == "status") {
$orderby = "domainstatus";
} else {
$orderby = "domain` " . $sort . ",`tblproducts`.`name";
}
$clientSslStatuses = WHMCS\Domain\Ssl\Status::where("user_id", $legacyClient->getID())->get();
$productCache = [];
$accounts = [];
$fields = "tblhosting.*,tblproductgroups.id AS group_id,tblproducts.name as product_name,tblproducts.tax,tblproductgroups.name as group_name,tblproducts.servertype,tblproducts.type";
$result = select_query($table, $fields, $where, $orderby, $sort, $limit, $innerjoin);
while ($data = mysql_fetch_array($result)) {
$id = $data["id"];
$productId = $data["packageid"];
$regdate = $data["regdate"];
$domain = $data["domain"];
$firstpaymentamount = $data["firstpaymentamount"];
$recurringamount = $data["amount"];
$nextduedate = $data["nextduedate"];
$billingcycle = $data["billingcycle"];
$status = $data["domainstatus"];
$tax = $data["tax"];
$server = $data["server"];
$username = $data["username"];
$module = $data["servertype"];
if(!isset($productCache["downloads"][$productId])) {
$productCache["downloads"][$productId] = WHMCS\Product\Product::find($productId)->getDownloadIds();
}
if(!isset($productCache["upgrades"][$productId])) {
$productCache["upgrades"][$productId] = WHMCS\Product\Product::find($productId)->getUpgradeProductIds();
}
if(!isset($productCache["groupNames"][$data["group_id"]])) {
$productCache["groupNames"][$data["group_id"]] = WHMCS\Product\Group::getGroupName($data["group_id"], $data["group_name"]);
}
if(!isset($productCache["productNames"][$data["packageid"]])) {
$productCache["productNames"][$data["packageid"]] = WHMCS\Product\Product::getProductName($data["packageid"], $data["product_name"]);
}
if(0 < $server && !isset($productCache["servers"][$server])) {
$productCache["servers"][$server] = get_query_vals("tblservers", "", ["id" => $server]);
}
$downloads = $productCache["downloads"][$productId];
$upgradepackages = $productCache["upgrades"][$productId];
$productgroup = $productCache["groupNames"][$data["group_id"]];
$productname = $productCache["productNames"][$data["packageid"]];
$serverarray = 0 < $server ? $productCache["servers"][$server] : [];
$normalisedRegDate = $regdate;
$regdate = fromMySQLDate($regdate, 0, 1, "-");
$normalisedNextDueDate = $nextduedate;
$nextduedate = fromMySQLDate($nextduedate, 0, 1, "-");
$langbillingcycle = $ca->getRawStatus($billingcycle);
$rawstatus = $ca->getRawStatus($status);
$legacyClassTplVar = $status;
if(!in_array($legacyClassTplVar, ["Active", "Completed", "Pending", "Suspended"])) {
$legacyClassTplVar = "Terminated";
}
$amount = $billingcycle == "One Time" ? $firstpaymentamount : $recurringamount;
$isDomain = filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
if($data["type"] == "other") {
$isDomain = false;
}
$isActive = in_array($status, ["Active", "Completed"]);
$sslStatus = NULL;
if($isDomain !== false && $isActive) {
$sslStatus = $clientSslStatuses->where("domain_name", $domain)->first();
if(is_null($sslStatus)) {
$sslStatus = WHMCS\Domain\Ssl\Status::factory($legacyClient->getID(), $domain);
}
}
$accounts[] = ["id" => $id, "regdate" => $regdate, "normalisedRegDate" => $normalisedRegDate, "group" => $productgroup, "product" => $productname, "module" => $module, "server" => $serverarray, "domain" => $domain, "firstpaymentamount" => formatCurrency($firstpaymentamount), "recurringamount" => formatCurrency($recurringamount), "amountnum" => $amount, "amount" => formatCurrency($amount), "nextduedate" => $nextduedate, "normalisedNextDueDate" => $normalisedNextDueDate, "billingcycle" => Lang::trans("orderpaymentterm" . $langbillingcycle), "username" => $username, "status" => $status, "statusClass" => WHMCS\View\Helper::generateCssFriendlyClassName($status), "statustext" => Lang::trans("clientarea" . $rawstatus), "rawstatus" => $rawstatus, "class" => strtolower($legacyClassTplVar), "addons" => get_query_val("tblhostingaddons", "id", ["hostingid" => $id], "id", "DESC") ? true : false, "packagesupgrade" => 0 < count($upgradepackages), "downloads" => 0 < count($downloads), "showcancelbutton" => (bool) WHMCS\Config\Setting::getValue("ShowCancellationButton"), "sslStatus" => $sslStatus, "isActive" => $isActive];
}
$ca->assign("services", $accounts);
$smartyvalues = array_merge($smartyvalues, clientAreaTablePageNav($numitems));
$ca->addOutputHookFunction("ClientAreaPageProductsServices");
} elseif($action == "productdetails") {
checkContactPermission("products");
$ca->setDisplayTitle(Lang::trans("manageproduct"));
$ca->setTemplate("clientareaproductdetails");
$service = new WHMCS\Service($id, $legacyClient->getID());
if($service->isNotValid()) {
redir("action=products", "clientarea.php");
}
$serviceModel = WHMCS\Service\Service::find($service->getID());
$ca->addToBreadCrumb("clientarea.php?action=products", $whmcs->get_lang("clientareaproducts"));
$ca->addToBreadCrumb("clientarea.php?action=productdetails#", $whmcs->get_lang("clientareaproductdetails"));
$customfields = $service->getCustomFields();
$domainIds = WHMCS\Domain\Domain::where("userid", $legacyClient->getID())->where("domain", $service->getData("domain"))->where("status", "Active")->pluck("id")->all();
if(count($domainIds) < 1) {
$domainIds = WHMCS\Domain\Domain::where("userid", $legacyClient->getID())->where("domain", $service->getData("domain"))->where("status", "!=", "Fraud")->pluck("id")->all();
}
if(count($domainIds) < 1) {
$domainIds = WHMCS\Domain\Domain::where("userid", $legacyClient->getID())->where("domain", $service->getData("domain"))->where("status", "Fraud")->pluck("id")->all();
}
if(count($domainIds) < 1) {
$domainId = "";
} else {
$domainId = array_shift($domainIds);
}
$ca->assign("id", $service->getData("id"));
$ca->assign("domainId", $domainId);
$ca->assign("serviceid", $service->getData("id"));
$ca->assign("pid", $service->getData("packageid"));
$ca->assign("producttype", $service->getData("type"));
$ca->assign("type", $service->getData("type"));
$ca->assign("regdate", fromMySQLDate($service->getData("regdate"), 0, 1, "-"));
$ca->assign("modulename", $service->getModule());
$ca->assign("module", $service->getModule());
$ca->assign("serverdata", $service->getServerInfo());
$ca->assign("domain", $service->getData("domain"));
$ca->assign("domainValid", str_replace(".", "", $service->getData("domain")) != $service->getData("domain"));
$ca->assign("groupname", $service->getData("groupname"));
$ca->assign("product", $service->getData("productname"));
$ca->assign("paymentmethod", $service->getPaymentMethod());
$ca->assign("firstpaymentamount", formatCurrency($service->getData("firstpaymentamount")));
$ca->assign("recurringamount", formatCurrency($service->getData("amount")));
$ca->assign("billingcycle", $service->getBillingCycleDisplay());
$ca->assign("nextduedate", fromMySQLDate($service->getData("nextduedate"), 0, 1, "-"));
$ca->assign("systemStatus", $service->getData("status"));
$ca->assign("status", $service->getStatusDisplay());
$ca->assign("rawstatus", strtolower($service->getData("status")));
$ca->assign("dedicatedip", $service->getData("dedicatedip"));
$ca->assign("assignedips", $service->getData("assignedips"));
$ca->assign("ns1", $service->getData("ns1"));
$ca->assign("ns2", $service->getData("ns2"));
$ca->assign("packagesupgrade", $service->getAllowProductUpgrades());
$ca->assign("configoptionsupgrade", $service->getAllowConfigOptionsUpgrade());
$ca->assign("customfields", $customfields);
$ca->assign("productcustomfields", $customfields);
$ca->assign("suspendreason", $service->getSuspensionReason());
$ca->assign("subscriptionid", $service->getData("subscriptionid"));
$isSitejetActive = WHMCS\Service\Adapters\SitejetAdapter::factory($serviceModel)->isSitejetActive();
$ca->assign("isSitejetActive", $isSitejetActive);
$ca->assign("isSitejetSsoAvailable", $isSitejetActive && Auth::hasPermission("productsso"));
$serviceModel = $service->getData("serviceModel");
$ca->assign("quantitySupported", $serviceModel->product->allowMultipleQuantities === WHMCS\Cart\CartCalculator::QUANTITY_SCALING);
$ca->assign("quantity", $service->getData("qty"));
$showRenewServiceButton = false;
$onDemandService = WHMCS\Service\ServiceOnDemandRenewal::factoryByService($serviceModel);
if($onDemandService->isRenewable()) {
$showRenewServiceButton = true;
}
unset($onDemandService);
$ca->assign("showRenewServiceButton", $showRenewServiceButton);
$isDomain = str_replace(".", "", $service->getData("domain")) != $service->getData("domain");
if($service->getData("type") == "other") {
$isDomain = false;
}
$sslStatus = NULL;
if($isDomain) {
$sslStatus = WHMCS\Domain\Ssl\Status::factory($legacyClient->getID(), $service->getData("domain"));
}
$ca->assign("sslStatus", $sslStatus);
$diskstats = $service->getDiskUsageStats();
foreach ($diskstats as $k => $v) {
$ca->assign($k, $v);
}
$availableAddonIds = [];
$availableAddonProducts = [];
if($service->getData("status") == "Active") {
$predefinedAddonProducts = $service->getPredefinedAddonsOnce();
$availableAddonIds = $service->hasProductGotAddons();
$availableAddonModels = WHMCS\Product\Addon::whereIn("id", $availableAddonIds)->isNotHidden()->isNotRetired()->get();
foreach ($availableAddonModels as $addonModel) {
$clientCurrencyCode = Auth::client()->getCurrencyCodeAttribute();
$enabledPricing = $addonModel->pricing($clientCurrencyCode)->allAvailableCycles();
if(empty($enabledPricing)) {
} else {
$availableAddonProducts[$addonModel->id] = $addonModel->name;
}
}
}
$ca->assign("showcancelbutton", $service->getAllowCancellation());
$ca->assign("configurableoptions", $service->getConfigurableOptions());
$ca->assign("addons", $service->getAddons());
$ca->assign("addonsavailable", $availableAddonIds);
$ca->assign("availableAddonProducts", $availableAddonProducts);
$ca->assign("downloads", $service->getAssociatedDownloads());
$ca->assign("pendingcancellation", $service->hasCancellationRequest());
$ca->assign("username", $service->getData("username"));
$ca->assign("password", $service->getData("password"));
$metrics = $serviceModel->metrics(true);
$metricStats = [];
if(WHMCS\UsageBilling\MetricUsageSettings::isCollectionEnable()) {
foreach ($metrics as $serviceMetric) {
if(!$serviceMetric->isEnabled()) {
} else {
$units = $serviceMetric->units();
$historicalUsage = $serviceMetric->historicUsage();
if($historicalUsage) {
$postPeriodDateRange = $historicalUsage->startAt()->toAdminDateFormat() . " - " . $historicalUsage->endAt()->toAdminDateFormat();
$postPeriodValue = $units->decorate($units->roundForType($historicalUsage->value()));
} else {
$postPeriodDateRange = "";
$postPeriodValue = "-";
}
$currentValue = $units->decorate($units->roundForType($serviceMetric->usage()->value()));
$pricing = [];
$pricingSchema = $serviceMetric->usageItem()->pricingSchema;
$freeLimit = $serviceMetric->usageItem()->included;
if(valueIsZero($freeLimit)) {
$freeLimit = NULL;
}
if(!$freeLimit) {
$freeLimit = $pricingSchema->freeLimit();
if(valueIsZero($freeLimit)) {
$freeLimit = NULL;
}
}
if($freeLimit) {
$freeLimit = $units->formatForType($freeLimit);
}
foreach ($pricingSchema as $bracket) {
$floor = 0;
if(!valueIsZero($bracket->floor)) {
$floor = $bracket->floor;
}
if($freeLimit) {
$floor = $floor + $freeLimit;
}
$floor = $units->formatForType($floor);
$currencyPrice = $bracket->pricingForCurrencyId($currency["id"]);
$pricing[] = ["from" => $floor, "price_per_unit" => formatCurrency($currencyPrice->monthly)];
$baseLangKey = "metrics.pricingschema." . $bracket->schemaType();
}
if(!$pricing) {
$baseLangKey = "metrics.pricingschema." . WHMCS\UsageBilling\Contracts\Pricing\PricingSchemaInterface::TYPE_SIMPLE;
$lowestPrice = "";
} else {
$lowestPrice = $pricing[0]["price_per_unit"];
}
$usage = $serviceMetric->usage();
if($usage instanceof WHMCS\UsageBilling\Contracts\Metrics\UsageStubInterface) {
$currentValue = $lastUpdated = "—";
} else {
$lastUpdated = $usage->collectedAt();
}
$metricStats[] = ["type" => $serviceMetric->type(), "systemName" => $serviceMetric->systemName(), "displayName" => $serviceMetric->displayName(), "unitName" => $units->perUnitName(1), "includedQuantity" => $freeLimit, "includedQuantityUnits" => $units->perUnitName($freeLimit), "lowestPrice" => $lowestPrice, "pricingSchema" => ["info" => Lang::trans($baseLangKey . ".info"), "detail" => Lang::trans($baseLangKey . ".detail")], "pricing" => $pricing, "postPeriodValue" => $postPeriodValue, "postPeriodDateRange" => $postPeriodDateRange, "currentValue" => $currentValue, "lastUpdated" => $lastUpdated];
}
}
}
$ca->assign("metricStats", $metricStats);
$hookResponses = run_hook("ClientAreaProductDetailsOutput", ["service" => $serviceModel]);
$ca->assign("hookOutput", $hookResponses);
$hookResponses = run_hook("ClientAreaProductDetailsPreModuleTemplate", $ca->getTemplateVariables());
foreach ($hookResponses as $hookTemplateVariables) {
foreach ($hookTemplateVariables as $k => $v) {
$ca->assign($k, $v);
}
}
$tplOverviewTabOutput = "";
$moduleClientAreaOutput = "";
$clientAreaCustomButtons = [];
$ca->assign("modulecustombuttonresult", "");
if(App::isInRequest("addonId") && 0 < (int) App::getFromRequest("addonId") && App::getFromRequest("modop") == "custom") {
$service = new WHMCS\Addon();
$service->setAddonId(App::getFromRequest("addonId"));
}
$smartyvalues["modulechangepwresult"] = NULL;
if($service->getModule()) {
$moduleInterface = new WHMCS\Module\Server();
if($service instanceof WHMCS\Addon) {
$moduleInterface->loadByAddonId($service->getID());
} else {
$moduleInterface->loadByServiceID($service->getID());
}
if($whmcs->get_req_var("dosinglesignon") && checkContactPermission("productsso", true)) {
if($service->getData("status") == "Active") {
try {
$redirectUrl = $moduleInterface->getSingleSignOnUrlForService();
header("Location: " . $redirectUrl);
exit;
} catch (WHMCS\Exception\Module\SingleSignOnError $e) {
$ca->assign("modulecustombuttonresult", $whmcs->get_lang("ssounabletologin"));
} catch (Exception $e) {
logActivity("Single Sign-On Request Failed with a Fatal Error: " . $e->getMessage());
$ca->assign("modulecustombuttonresult", $whmcs->get_lang("ssofatalerror"));
}
} else {
$ca->assign("modulecustombuttonresult", Lang::trans("productMustBeActiveForModuleCmds"));
}
} elseif($whmcs->get_req_var("dosinglesignon")) {
$ca->assign("modulecustombuttonresult", Lang::trans("subaccountSsoDenied"));
}
if(App::getFromRequest("doaddonsignon") && checkContactPermission("productsso", true)) {
if($service->getData("status") === WHMCS\Utility\Status::ACTIVE) {
try {
$addonAutomation = WHMCS\Service\Automation\AddonAutomation::factory((int) App::getFromRequest("addonId"));
$redirectUrl = $addonAutomation->singleSignOnAddOnFeature();
header("Location: " . $redirectUrl);
WHMCS\Terminus::getInstance()->doExit();
} catch (Exception $e) {
logActivity("Single Sign-On Request Failed with a Fatal Error: " . $e->getMessage());
$ca->assign("modulecustombuttonresult", Lang::trans("ssofatalerror"));
}
}
} elseif(App::getFromRequest("doaddonsignon")) {
$ca->assign("modulecustombuttonresult", Lang::trans("subaccountSsoDenied"));
}
if(App::getFromRequest("customaction_error")) {
$ca->assign("modulecustombuttonresult", WHMCS\Session::getAndDelete("customaction_error"));
} elseif(App::getFromRequest("customaction_ajax_error")) {
$ca->assign("modulecustombuttonresult", Lang::trans("customActionGenericError"));
}
$moduleFolderPath = $moduleInterface->getBaseModuleDir() . DIRECTORY_SEPARATOR . $service->getModule();
$moduleFolderPath = substr($moduleFolderPath, strlen(ROOTDIR));
$allowedModuleFunctions = [];
$success = $service->moduleCall("ClientAreaAllowedFunctions");
if($success) {
$clientAreaAllowedFunctions = $service->getModuleReturn("data");
if(is_array($clientAreaAllowedFunctions)) {
foreach ($clientAreaAllowedFunctions as $functionName) {
if(is_string($functionName)) {
$allowedModuleFunctions[] = $functionName;
}
}
}
}
$success = $service->moduleCall("ClientAreaCustomButtonArray");
if($success) {
$clientAreaCustomButtons = $service->getModuleReturn("data");
if(is_array($clientAreaCustomButtons)) {
foreach ($clientAreaCustomButtons as $buttonLabel => $functionName) {
if(is_string($functionName)) {
$allowedModuleFunctions[] = $functionName;
}
}
}
}
$moduleOperation = $whmcs->get_req_var("modop");
$moduleAction = $whmcs->get_req_var("a");
if($serverAction = $whmcs->get_req_var("serveraction")) {
$moduleOperation = $serverAction;
}
if($moduleOperation == "custom" && in_array($moduleAction, $allowedModuleFunctions)) {
if($service->getData("status") == "Active") {
checkContactPermission("manageproducts");
$success = $service->moduleCall($moduleAction);
if($success) {
$data = $service->getModuleReturn("data");
if(is_array($data)) {
if(isset($data["jsonResponse"])) {
$response = new WHMCS\Http\JsonResponse();
$response->setData($data["jsonResponse"]);
$response->send();
exit;
}
if(isset($data["overrideDisplayTitle"])) {
$ca->setDisplayTitle($data["overrideDisplayTitle"]);
}
if(isset($data["overrideBreadcrumb"]) && is_array($data["overrideBreadcrumb"])) {
$ca->resetBreadCrumb()->addToBreadCrumb("index.php", $whmcs->get_lang("globalsystemname"))->addToBreadCrumb("clientarea.php", $whmcs->get_lang("clientareatitle"));
foreach ($data["overrideBreadcrumb"] as $breadcrumb) {
$ca->addToBreadCrumb($breadcrumb[0], $breadcrumb[1]);
}
}
if(isset($data["appendToBreadcrumb"]) && is_array($data["appendToBreadcrumb"])) {
foreach ($data["appendToBreadcrumb"] as $breadcrumb) {
$ca->addToBreadCrumb($breadcrumb[0], $breadcrumb[1]);
}
}
if(isset($data["outputTemplateFile"])) {
$ca->setTemplate($moduleInterface->findTemplate($data["outputTemplateFile"]));
} elseif(isset($data["templatefile"])) {
$ca->setTemplate($moduleInterface->findTemplate($data["templatefile"] . ".tpl"));
}
if(isset($data["breadcrumb"]) && is_array($data["breadcrumb"])) {
foreach ($data["breadcrumb"] as $href => $label) {
$ca->addToBreadCrumb($href, $label);
}
}
if(is_array($data["templateVariables"]) || is_array($data["vars"])) {
$templateVars = isset($data["templateVariables"]) ? $data["templateVariables"] : $data["vars"];
foreach ($templateVars as $key => $value) {
$ca->assign($key, $value);
}
}
} else {
$ca->assign("modulecustombuttonresult", "success");
}
} else {
$ca->assign("modulecustombuttonresult", $service->getLastError());
}
} else {
$ca->assign("modulecustombuttonresult", Lang::trans("productMustBeActiveForModuleCmds"));
}
}
$smartyvalues["modulechangepwresult"] = "";
if($service->getData("status") == "Active" && $service->hasFunction("ChangePassword") && $service->getAllowChangePassword()) {
$ca->assign("serverchangepassword", true);
$ca->assign("modulechangepassword", true);
$modulechangepasswordmessage = "";
$modulechangepassword = $whmcs->get_req_var("modulechangepassword");
if($whmcs->get_req_var("serverchangepassword")) {
$modulechangepassword = true;
}
if($modulechangepassword) {
check_token();
checkContactPermission("manageproducts");
$newpwfield = "newpw";
$newpassword1 = $whmcs->get_req_var("newpw");
$newpassword2 = $whmcs->get_req_var("confirmpw");
foreach (["newpassword1", "newserverpassword1"] as $key) {
if(!$newpassword1 && $whmcs->get_req_var($key)) {
$newpwfield = $key;
$newpassword1 = $whmcs->get_req_var($key);
}
}
foreach (["newpassword2", "newserverpassword2"] as $key) {
if($whmcs->get_req_var($key)) {
$newpassword2 = $whmcs->get_req_var($key);
}
}
$validate = new WHMCS\Validate();
if($validate->validate("match_value", "newpw", "clientareaerrorpasswordnotmatch", [$newpassword1, $newpassword2])) {
$validate->validate("pwstrength", $newpwfield, "pwstrengthfail");
}
if($validate->hasErrors()) {
$modulechangepwresult = "error";
$modulechangepasswordmessage = $validate->getHTMLErrorOutput();
} else {
update_query("tblhosting", ["password" => encrypt($newpassword1)], ["id" => $id]);
$updatearr = ["password" => WHMCS\Input\Sanitize::decode($newpassword1)];
$success = $service->moduleCall("ChangePassword", $updatearr);
if($success) {
logActivity("Module Change Password Successful - Service ID: " . $id);
HookMgr::run("AfterModuleChangePassword", ["serviceid" => $id, "oldpassword" => $service->getData("password"), "newpassword" => $updatearr["password"]]);
$modulechangepwresult = "success";
$modulechangepasswordmessage = Lang::trans("serverchangepasswordsuccessful");
$ca->assign("password", $newpassword1);
} else {
$modulechangepwresult = "error";
$modulechangepasswordmessage = Lang::trans("serverchangepasswordfailed");
update_query("tblhosting", ["password" => encrypt($service->getData("password"))], ["id" => $id]);
}
}
$smartyvalues["modulechangepwresult"] = $modulechangepwresult;
$smartyvalues["modulechangepasswordmessage"] = $modulechangepasswordmessage;
}
}
$customTemplateVariables = $ca->getTemplateVariables();
$customTemplateVariables["moduleParams"] = $moduleInterface->buildParams();
$moduleTemplateVariables = [];
$tabOverviewModuleDirectOutputContent = "";
$tabOverviewModuleOutputTemplate = "";
$tabOverviewReplacementTemplate = "";
if($service->hasFunction("ClientArea")) {
$inputParams = ["clientareatemplate" => App::getClientAreaTemplate()->getName(), "templatevars" => $customTemplateVariables, "whmcsVersion" => App::getVersion()->getCanonical()];
$success = $service->moduleCall("ClientArea", $inputParams);
$data = $service->getModuleReturn("data");
if(is_array($data)) {
if(isset($data["overrideDisplayTitle"])) {
$ca->setDisplayTitle($data["overrideDisplayTitle"]);
}
if(isset($data["overrideBreadcrumb"]) && is_array($data["overrideBreadcrumb"])) {
$ca->resetBreadCrumb()->addToBreadCrumb("index.php", $whmcs->get_lang("globalsystemname"))->addToBreadCrumb("clientarea.php", $whmcs->get_lang("clientareatitle"));
foreach ($data["overrideBreadcrumb"] as $breadcrumb) {
$ca->addToBreadCrumb($breadcrumb[0], $breadcrumb[1]);
}
}
if(isset($data["appendToBreadcrumb"]) && is_array($data["appendToBreadcrumb"])) {
foreach ($data["appendToBreadcrumb"] as $breadcrumb) {
$ca->addToBreadCrumb($breadcrumb[0], $breadcrumb[1]);
}
}
if(isset($data["tabOverviewModuleOutputTemplate"])) {
$tabOverviewModuleOutputTemplate = $moduleInterface->findTemplate($data["tabOverviewModuleOutputTemplate"]);
} elseif(isset($data["templatefile"])) {
$tabOverviewModuleOutputTemplate = $moduleInterface->findTemplate($data["templatefile"]);
}
if(isset($data["tabOverviewReplacementTemplate"])) {
$tabOverviewReplacementTemplate = $moduleInterface->findTemplate($data["tabOverviewReplacementTemplate"]);
}
if(isset($data["templateVariables"]) && is_array($data["templateVariables"])) {
$moduleTemplateVariables = $data["templateVariables"];
} elseif(isset($data["vars"]) && is_array($data["vars"])) {
$moduleTemplateVariables = $data["vars"];
}
} else {
$tabOverviewModuleDirectOutputContent = $data != WHMCS\Module\Server::FUNCTIONDOESNTEXIST ? $data : "";