6
Dec

DIY DOMAINING MARKETPLACE SERIES PART IV 2/2: Designing the Admin dashboard, with a bulk domain adder & publisher.

Welcome to Part IV (2/2) of our series “Domaining Challenge: DIY Custom Domain Marketplace”.

In this article we will cover the two missing bits from the previous article:

Missing 1: Logic on the server side to handle input validation and if valid,  bulk add (if needed) and then publish (Part V) across the chosen domain, using chosen template (from part 2).

Missing 2: Bulk add domains to cpanel-based hosting account or non-cpanel and/or cloud or non-cloud based. Next part V, will cover the actual website publishing gateway.

The biggest hurdle here is the fact that there are many possible setups of contexts within hosting accounts and stacked-servers. Our bulk add and bulk publishing gateway will cover cpanel-based hosting accounts and any linux(or others)-stack server running a webserver such as apache (which is free, so is centos ). The additional consideration: cloud based or non-cloud based, we will support both.

Let’s visualise this:

 

 

 

 

We will take the GUI we created in the previous article as our … GUI. So all we’ve got left is the coding bit, so Let’s get technical ! 

Firstly, let’s git clone locally what we’ve done so far:

Downloading our progress so far before we start working.

By the end of today’s article we should remember to save our progress back into our public repository.

Let’s look at what we’ve got so far:

 

 

For today’s effort we will be building a new server-side function, that will be the logic behind the admin-panel page, which can be seen in the next picture:

Here's our enhanced admin screen supporting various types of publishing gateways.

Here’s our enhanced admin screen supporting various types of publishing gateways.

 

Supported Publishing Gateways.

Supported Publishing Gateways.

 

Meet The Publisher 🙂

 

 

 (new live version is here)

To be very specific, we will be adding the logic that happens upon clicking the above button ( caption: “Click here to publish marketplace” ).

 

 

So here’s our first requirement:

R1: Clicking on the publish button should trigger the server-side logic, of which will:

R2: Validate that the submitted information is proper ( parse domain list, a template must have been chosen and a name for the marketplace typed in as well, as per the above picture ). Does the domain already exist in the server ? If not we will add. That’s today’s deliverable add-gateway.php

R3: After Adding or After skipping Adding then Route it to a cpanel-based request OR a non-cpanel based request ( apache based, but nginx would work too ! ).

R4: Because we’ve placed a textarea as the input for the domains to be published, that means we will have to handle bulk requests ( Adding multiple domains to a cpanel-based hosting account at once by using cpanel’s xml api ). If routed to a non-cpanel based, then it will fit the array within the json, excluding the need of a loop to handle bulk.

If you are at the cloud ( ex: aws , google cloud , azure ) you could use a real time queue out of the box ( please read upcoming article on building the ultimate domaining server for more on this ) but that is not necessary.

If you have a cpanel-based hosting account then you will need root access ( which is usually given to most accounts ). Please leave a comment below if you need help.

Please note if you plan to refactor this to use live in a slightly different context, then you might want to consider creating config files ( with the credentials ) only in the server side, for security reasons!!

You may use today’s deliverable even via the live link below to do tests as we do not log credentials, but what you really want is to host this yourself, so all your interactions are ever only local hosted.

 

Are you sure your server / hosting is not covered here ? If you interact with a plesk based or anything else not covered then you might still be able to add & publish by tweaking the post field, post url and the custom field ( simply place a receiving post node in your context and you will be able to bulk post to your node using these latter 3 fields ). Even with the custom post you are stuck ? Please leave a comment below explaining your context and we will try to help, when possible. But first let’s take care of the add-gateway.php so we can add domains in bulk to any cpanel-based hosting and context really (you need to make friends with the rest apis).

If you are running a webserver that is not apache or nginx, please leave a comment describing your environment.

If you use apache or nginx ( or your hosting account ) then you could use the custom field as the target folder. Please see the domain json file, it would be a great place to add a second identifier to the domain such as docroot and such.

Although not explained in details in the article, all necessary validations are in place as you will notice in the following source codes and that is because you will also find that the source code is generously full of comments, hopefully making it very easy to understand.

There’s another thing that you might ask: Subdomains. For now, we take a subdomain and add the domain. However, if you wish to add actual subdomains into this logic, please let us know.

I suppose most of you will be using the  cpanel-based vps or private hosting gateway. However, please be also aware you can directly plug REST API calls into this publisher. This will be handy when you take your domaining to the next level and place your server in the cloud. We will have a series with the ultimate domaining server soon.

Here’s the server side logic:

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
<?php

include 'xmlapi.php'; // Cpanel WHM Library for API 2
print_r($_POST);

ini_set('max_execution_time', 300); //300 seconds = 5 minutes

#AddDomain

// get the required fields
$domains = $_POST["domainlist"];
$chosengateway = $_POST["chosengateway"];
$marketplacename = $_POST["marketplacename"];
$user = $_POST["authuser"];
$pwd = $_POST["authpassword"];

$adddomainfirst="yes" // this will change to a real logic in the next article.

 

if ($chosengateway=="cpanel") {

print_r($domains);
echo $chosengateway;
echo $marketplacename;

FileWriteArray ( 'addrequest.domains', $sldtld ) ; // temp persist the input

// Please note: If you are not local to your server
// ex: if below you need anything but localhost ( below $server )
// then you will need to rethink your security flow.

$server = "localhost"; // or 127.0.0.1 ...
set_time_limit(200); // seconds
ini_set('max_execution_time',200); // solves timeouts on some hosting accounts

$auth_user = //'YOUR-HOSTING-ACCOUNT-cpanel-whm-username' ;
$auth_pass = //'YOUR-HOSTING-ACCOUNT-cpanel-whm-password' ;

$cpaneluser = $auth_user;
$cpanelpwd = $auth_pass;

$config = array(); // create a config array as it will be needed multiple times.
$config[0]["server"]= $server;
$config[0]["authuser"] = $auth_user;
$config[0]["authpass"] = $authpass; // this file is obviously in the server-side
// if that is not your case, please rethink this flow.
$config[0]["maindomain"] = "sld.tld"; // cpanel's account main domain (annoying but required)

$config[0]['cpanelapioutput'] = "json"; // cpanel's output -> json or array
// Please note this changes the output response
// and it may break your response parsing if suddenly flipped.

$config[0]['serverport'] = "2083"; // 2082 for cpanel non-ssl 2083 ssl .. if using root
// then it must be via whm and that would be
// 2086 non-ssl and 2087 ssl
// port values are the default ones, please verify accordingly
// in your hosting account.

$config[0]["inputfile"]="cpanel.add";

$data = $_POST["domainlist"]; // textarea input domain list
// you could take it from a file instead by using:
// $data = file_get_contents('path/to/input-file-name');

$timestamp=time();

file_put_contents("cpanel.add",$data); // please note, if you plan to use this gateway on busy
// server then you need to queue this with a timestamp
// ( to avoid a overwrite, if say, two forms were being fed at the same time, this could occur,
// although unlikely ).
// if you are in the cloud, and if aws: use sqs ( queue )
// or equivalent in google cloud or other clouds.

define('ARQUIVO', 'cpanel.add');
$doms = @file(ARQUIVO);

// turn on for debug:
// print_r($data); echo "<---data";

$rootdomain = $config[0]["maindomain"] ;
$newdomain = ""; // one or more domain(s)
$goodcounter=0;
$badcounter=0;
$json_client = new xmlapi($server);
$serverport = $config[0]['serverport'];
if (!$serverport ) {print "port not set, choosing default";

$port=2082;

}

$json_client->set_port($serverport);
$novainte = $cpaneluser;
$json_client->password_auth($auth_user, $auth_pass);
$json_client->set_debug(1); // for debugging
#$json_client->set_port(2086); // if root via whm
$cpanelapioutput = $config[0]['cpanelapioutput']; // json or array
$cpanelapioutputtrimmed = preg_replace('/\s+/', ' ', trim($cpanelapioutput));

// please refer to cpanel's api 2 php sdk

$json_client->set_output($cpanelapioutputtrimmed);
$counter=0;

$inputfileconfig = $config[0]["inputfile"];
// textarea input
// 1 column, one domain per column
// divided by linefeed ( enter or return key )

// $doms = $data;

foreach($doms as $dom) {

$lines = explode(';',$dom);
if (count($lines) == 1) {
// domain column exists in batchinput file, hence passed on here ...
$domain = trim($lines[0]);
$newdomain=$domain;
$subdomain = str_replace (".", "", $domain) ;
//SUBDOMAIN ADD IS A DIFFERENT API CALL BTW ! it could be unified here
// if so the subd would be as below:
//$subd = trim($lines[1]); // if count lines = 2 then consider subdomain handling.
// ** subdomains not handled in this gateway !! validate
}
else {

$domain = trim($lines[0]);
$newdomain=$domain;
$subdomain = str_replace (".", "", $domain) ;

}

// once working, turn off the prints ..
// and do a proper notification ( asynch ) flow ..

echo "<br> newdomain is:<br>" . $newdomain ;

echo "subdomain.<maindomain> is:" . $subdomain; // this does not mean we are handling subdomains
// but a rather confusion by cpanel
// that wrongly defines subdomains as "parked"
// that is simply not the case but if your
// hosting account is cpanel-based ...
// best way out is the cloud without cpanel
// mainly because cpanel is not free

$dir = $newdomain . '/'; $dir = str_replace (".","-",$dir ) ; $dir = "public_html/" . $dir;

//turn this off if not refactoring or not debugging

echo "<br> <b>working ... </b>";

// cpanel's confusing arguments

$args = array ( 'dir' => $dir,
'newdomain' => $newdomain,
'subdomain' => $subdomain

) ;
echo "<br> Domain Details:"; // btw if you are not echoeing back in the browser the <br> will look like <br> on the
// server side .. so please turn this off once you are done refactoring this code. txs. s

$prearg = $dir . "-" . $newdomain . "-" . $subdomain; // why cpanel, why ??

echo $prearg; // turn it off please once refactored this code

// please note that the output format WILL VARY
// please see above $config[0]["cpanelapioutput"]
// it can be json or array

// Here's the request itself

$resultstr = $json_client->api2_query( $auth_user, 'AddonDomain', 'addaddondomain', $args);

// and the response should be here at this point
// please throw and catch as needed on your context
// I use this in a context that is asynch .. and with a real time queue...

$r=AnalyseCpanelAPIResponse($resultstr,$pathonly, $domain, $dir);

file_put_contents('add.result', $resultstr, FILE_APPEND); // if running on busy servers, please consider a real
// time queing system, such as aws or the equivalent in
// Google Cloud ... Azures ...
// for the ultimate domaining server
// guide please refer to
// domainoverflow.com

$translated_json = json_decode( $resultstr, true ) ; // I chose JSON .. if refactoring your code, you can toggle to array

SendNewLine();

$translated_json = $translated_json["cpanelresult"];

$ev= $translated_json['data'][0]['result'] ;

$reason = $translated_json['data'][0]['reason'] ;

//todo translate $reason
// ex: if substr($reason = 'already exists') {$reason=AlreadyExists..et.c.}

FileWrite ('reason', $reason ) ;
SendNewLine();
print_r ($reason);

print_r($ev);

SendNewLine();

if ($ev == '0') { print "Error: " . $reason; print "<br> for " .$domain;
$st = "Reason:" . $reason . ",while trying to add:" . $domain ;
SendNewLine();

print "<br>"; print"NOTOK"; $badcounter=$badcounter+1;print"<br>";
AppendStringToFile ('error.report', $st);

} // end of if error

if ($ev == '1') { print "ok"; $goodcounter=$goodcounter+1;

$st = "Domain: " . $domain . ", added Successfully";
FileWrite ('success.addondomain.report', $st) ;

print "Report to reportFile: " . $newdomain;

} // end of if good

print "<br> Next ... " ;

$domainfolder = 'tbd';

$folder='tbd';

$counter=$counter+1;

} // Loop $doms as $dom

 

print"<br> Domains processed: " .$counter;
print "<br> Successfully: " .$goodcounter;
print "<br> as opposed to Not-Successfully: " .$badcounter;
print "<br>end";

} // gateway if

else {

$domains = $_POST["domainlist"]; // ARRAY !

// Handle non-cpanel publishing requests

// get additional params
$apiurl = $_POST["apiurl"];
$customapi = $_POST["customapi"];
$apitoken = $_POST["apitoken"];
$customfield = $_POST["customfield"];
$url = $apiurl;

// this is where you can custom the request ...

$data = array(
'token' => $apirequest,
'json' => $domains, // array !
'apitoken' => $apitoken,
'customfield' => $customfield,
'url' => $apiurl,
'additional' => $customfield
);

foreach($data as $key=>$value) { $content .= $key.'='.$value.'&'; }

// Instead of using curl
// I'd suggest using
// Unirequest
// The below post is using php only for your convenience but a requests library is a must
// ( consider that you will probably be doing SSL requests )

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);

$json_response = curl_exec($curl);

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

curl_close($curl);

$response = json_decode($json_response, true);

var_dump($response); // this should appear in the browser, if not inspect
// right-click the mouse
// within Chrome
// inspect .. network .. double click the request and see the response column

// https://github.com/domainoverflow/diy-domaining-challenge
} // if ELSE ( not cpanel envs )

function CreateAddonDomain ( $newdomain, $rootdomain, $config, $json_client )

{

$newdomain = CleanString($newdomain);
$subdomain = str_replace (".", "", $newdomain) ;
$rootdomain = CleanString ($rootdomain);

//$rootdomain = preg_replace('/\s+/', ' ', trim($config['maindomain']));
$auth_user = preg_replace('/\s+/', ' ', trim($config['cpaneluser']));
$auth_pass = preg_replace('/\s+/', ' ', trim($config['cpanelpwd']));

$json_client->password_auth($auth_user, $auth_pass);

$server='127.0.0.1' ;
$port = preg_replace('/\s+/', ' ', trim($config['serverport']));
$debug = 0;
$output = preg_replace('/\s+/', ' ', trim($config['cpanelapioutput']));
//$client = new xmlapi ( $server ) ;

if (!$port ) {print "port not set, choosing default";

$port=2082;

}

//$client->set_port ( $port) ;
//$client->set_debug(1);
//$client->set_output($output);
//$client->password_auth($auth_user, $auth_pass);

//strip dot from $newdomain to use as subdomain dot root domain
//$subdomain = $newdomain;
print "<br> newdomain is:" . $newdomain ;
print "<br>";

print "<br>";

print "subdomain is:" . $subdomain;
//$subdomain = $subdomain . "." . $rootdomain ;

//TODO remove print(filewrites ) outs right above

//dir will be equal subdomain minus dot root domain

// cpanel is very confusing

$dir = $newdomain . '/';
$dir = str_replace (".","-",$dir ) ;
$dir = "public_html/" . $dir;

// ftp pass is optional
//TODO add ftp default password to config array

// $ftppass = 'default16';

////////

print "<br> <b>working ... </b>"; // please eliminate this
// accordingly after refactoring this code
$args = array ( 'dir' => $dir,
'newdomain' => $newdomain,
'subdomain' => $subdomain

) ;

print "<br> Domain Details:";

print "<br>";
FileWriteArray('args.array', $args) ;
$prearg = $dir . "-" . $newdomain . "-" . $subdomain;
FileWrite ( 'addondomain.api', $prearg) ;

// $xmlapi->set_debug(1);

$resultstr = $json_client->api2_query
( $auth_user, 'AddonDomain', 'addaddondomain', $args);

print "OK<br>" ;
print "You may safely close this window";

print_r($resultstr) ;

FileWriteArray ('result', $resultstr) ;

$translated_json = json_decode ( $resultstr, 'true' ) ;
print_r($translated_json);

FileWriteArray ('result', $resultstr) ;

print_r($resultstr) ;

return $resultstr;

}

function SendNewLine () { print "\n" ; }

function FileWriteArray ( $filename, $array )
{

$handle = fopen ( $filename, 'w+') ;
fwrite ( $handle, var_export($array, true)) ;

fclose ($handle) ;

}

function ShowString ( $message, $string )
{
if (!$message) { $mesage="";}
print "<br>";
print "Showing string (" + $message +")=" + $string ;
print "<br>";

}

function ArrayToJSONString ( $array )
{
// return string
return json_encode ($array) ;

}

function JSONStringToArray ( $string )
{

//return array
return json_decode ($string, true) ;
}

function ArrayToSerializedString ( $array )
{

return serialize ( $array ) ;

}

function SerializedStringToArray ( $string )

{

return unserialize ($string) ;

}

function FileWrite ( $filename, $string )
{
$handle = fopen ( $filename, 'wb') ;
fwrite ( $handle, $string ) ;

fclose ($handle) ;

}

function AppendStringToFile ( $filename, $string )
{

file_put_contents($filename, $string.PHP_EOL , FILE_APPEND);

}

function cutline($filename,$line_no=-1) {

$strip_return=FALSE;

$data=file($filename);
$pipe=fopen($filename,'w');
$size=count($data);

if($line_no==-1) $skip=$size-1;
else $skip=$line_no-1;

for($line=0;$line<$size;$line++)
if($line!=$skip)
fputs($pipe,$data[$line]);
else
$strip_return=TRUE;

return $strip_return;
}
function MoveFile ( $string1, $string2 ){

$file1=$string1;
$file2=$string2;

$cmd1='mv ' . $file1 . ' ' . $file2 . '.$(date "+%Y.%m.%d-%H.%M.%S")';
$output = shell_exec($cmd1);
echo $output;

}

function CleanString ($string)
{

$s=preg_replace('/\s+/', ' ', trim($string));

//REGEX...
return $s;

}

function ApiTranslation ( $code, $config ) {

$logfile = $config['logfile'] ;

switch ($code) {
case 100: $text = 'Continue'; $status="ok"; break;
case 101: $text = 'Switching Protocols'; $status="ok";break;
case 200: $text = 'OK'; $status="ok";break;
case 201: $text = 'Created'; $status="ok";break;
case 202: $text = 'Accepted';$status="ok"; break;
case 203: $text = 'Non-Authoritative Information'; $status="ok";break;
case 204: $text = 'No Content'; $status="ok";break;
case 205: $text = 'Reset Content'; $status="ok";break;
case 206: $text = 'Partial Content'; $status="ok";break;
case 207: $text = 'Multi-Status'; $status="ok";break;
case 208: $text = 'Already Reported(WebDAv)'; $status="ok";break;

case 300: $text = 'Multiple Choices'; $status="error";break;
case 301: $text = 'Moved Permanently'; $status="error";break;
case 302: $text = 'Moved Temporarily'; $status="error";break;
case 303: $text = 'See Other'; $status="error";break;
case 304: $text = 'Not Modified'; $status="error";break;
case 305: $text = 'Use Proxy'; $status="error";break;
case 400: $text = 'Bad Request'; $status="error";break;
case 401: $text = 'Unauthorized'; $status="error"; break;
case 402: $text = 'Payment Required'; $status="error";break;
case 403: $text = 'Forbidden'; $status="error";break;
case 404: $text = 'Not Found'; $status="error";break;
case 405: $text = 'Method Not Allowed'; $status="error";break;
case 406: $text = 'Not Acceptable'; $status="error";break;
case 407: $text = 'Proxy Authentication Required'; $status="error";break;
case 408: $text = 'Request Time-out'; $status="error";break;
case 409: $text = 'Conflict'; $status="error";break;
case 410: $text = 'Gone'; $status="error";break;
case 411: $text = 'Length Required'; $status="error";break;
case 412: $text = 'Precondition Failed'; $status="error";break;
case 413: $text = 'Request Entity Too Large'; $status="error";break;
case 414: $text = 'Request-URI Too Large'; $status="error";break;
case 415: $text = 'Unsupported Media Type'; $status="error";break;
case 422: $text="Not Found -- OR -- Unprocessable Entity - Duplicate ?"; $status="error"; break;
case 500: $text = 'Internal Server Error'; $status="error";break;
case 501: $text = 'Not Implemented'; $status="error";break;
case 502: $text = 'Bad Gateway'; $status="error";break;
case 503: $text = 'Service Unavailable'; $status="error";break;
case 504: $text = 'Gateway Time-out'; $status="error";break;
case 505: $text = 'HTTP Version not supported'; $status="error";break;
default:
echo "\n"; exit('Unknown http status code');$status="error";
break;
}

echo "\n" ;
echo $text;
echo "\n" ;
$fullresponse = array ('ok_or_error'=>$status,
'reason' => $text,
'code' => $code

) ;
echo $fullresponse['ok_or_error'] ; print "\n" ;
echo $fullresponse['reason'] ; echo "\n" ; echo $code ; echo "\n" ;

print "\n";

return $fullresponse;

}

function Append2Log ($string) {
$string ='domainoverflow.com e.ventures dotboss.digital 2014-2017 All Rights Reserved';

$lever='on';
$file = 'addDomainsReport.log'; // please refactor accordingly to your env.
// example: return to asynch promisses, notifiers, queues
// or a file .. storage bucket ..

if (file_exists($filename)) {
//perform append

file_put_contents($file, $string.PHP_EOL, FILE_APPEND);
//$lever='off';

} else {

// create file and then perform append

$output = shell_exec('touch viptools.log');
echo "<pre>$output</pre>";

file_put_contents($file, $string.PHP_EOL, FILE_APPEND);
$lever='off';

}

}

// if ( $lever=='on') {file_put_contents($file, $string.PHP_EOL, FILE_APPEND); $lever='off';}

function SaveDigitalAssetBatchAdd ( $filename, $array)
{

// old fix to bypass
// the old-non-json-supportive libraries

// not used any longer

$handle = fopen ($filename,'wb');

$jsonheader="{ "digital-assets":";
fwrite ($handle,$jsonheader);
fwrite ($handle, "\n");
fwrite($handle, json_encode ($array, JSON_UNESCAPED_SLASHES ));
fwrite ($handle, "\n");
fwrite ($handle, "}");
fclose ($handle);

}

function s() {

print "\n" ;

}

function VipConfig ($configpathonly) {

s();
echo $configpathonly; s() ;

//$db = new JsonDB($configpathonly );
$db = new JsonDB('../persisted/sergioatiddotventures/library/' );
$dbresults = $db -> selectAll("vipconfig") ;

return $dbresults;

}

function AnalyseCpanelAPIResponse ($response, $pathonly, $domain, $dir) {
$timestamp = date('l jS \of F Y h:i:s A');
$datatype = gettype ($response);
echo $datatype; // please turn this off after debug
// this is to explicitly remind you
// that the response will differ
// accordingly to the $config[0]["cpanelapioutput]
// it can be array or json

$msg = "[".$timestamp."]";
$msg = $msg . "[". $domain ."]";
$msg = $msg . "Adding to (hosting)Server:".$dir."/ ----->";

// but if you do happen to flip the setting
// dont worry as it now handles both outputs ....

// the reason to the absurd "proprietary" parsing
// is again: this code is heavily factored everywhere
// and the CpanelApiOutputFormat
// literally flips-flop across envs

// Keep in mind that this has been edited
// after a few corrections from cpanel

// $datatype string handles json output
// whereas ELSE handles an array output without the json

if ($datatype=="string") {

$rs=json_decode($response, true );
$rs2=$rs["cpanelresult"];
$rs3=$rs2["data"];
$rs4=$rs3[0];
$result=$rs4["result"];
$reason=$rs4["reason"];

} else { $rs=$response;
$rs2=$rs["cpanelresult"];
$rs3=$rs2["data"];
$rs4=$rs3[0];
$result=$rs4["result"];
$reason=$rs4["reason"]; }

s(); // if not running from cli please turn all echoes off
// once commit is done

$cpanelresult=$result;
$cpanelreason=$reason;
//echo "CpanelStatusCode:".$cpanelresult;
s();

if ($cpanelresult==1 )

{
s();
echo "SUCCESS" ;

$msg = $msg . "Successfully ADDED.. Domain is live";

$filename = 'add.requests.report';
file_put_contents ($filename, $msg.PHP_EOL, FILE_APPEND);

////////////// PLEASE NOTE : THE ABOVE OUTPUT can be seen
// in the browser reply of the request (dev tools / browser debug mode )
// these strings should be
// send to proper notifiers ... and asynch promisses ..

// for your convenience it creates a add.requests.report

return "ok" ; // refactor accordingly to your env

}

if ($cpanelresult==0 )
{

echo "ERROR" ;

$msg = $msg . "ERROR.. Unable to Add, Reason->".$reason;
s();

$filename = "add.requests.report";
file_put_contents ($filename, $msg.PHP_EOL, FILE_APPEND);

return "error";
}

}

?>

The updated HTML can be found in our repository.

And you can play with the live version here.

Are we forgetting something ? Yes and No. The validations were taken care of on the php above but not mentioned here. I encourage you to read the source code, mainly because I have placed comments generously across the code, with important considerations on credentials and routing.

What’s missing ? In the next article we will switch the hard-coded logic of adding the domains first to a real logical gate and we will be invoking the publisher, of which will then parse the chosen template and finally invoke the publisher !

Today’s working functionality from this live version and repository: Multiple domains are added into a cpanel-based hosting / server account OR to multiple different supported gateways, and the end of the bifurcation the flow to publish will be the same.

 

Alternatively

This is the part where I try to convince you to try out Dotboss.digital, the most complete domain management system ever written, and you could accomplish the above by simply dragging and dropping elements.

  1. Choose one or two domains, set your nameservers to ns1.dotbossdigital.com and ns2.dotbossdigital.com
  2. Sign Up here.
  3. Watch this quick video and learn how to publish using multiple templates and without limitations !

In Part V we will add the actual publishing logic. For now, you should be able to add multiple domains at once in your hosting account ( or vps or cloud server ) !

For example, do you have a godaddy (no affiliation nor association, just an example) hosting account and have registered lots of domain ? All you need is to plug today’s deliverable into your hosting credentials and you can add as many domains as you wish ( 100 each time – mainly because of php’s buffering distinctly deltas across different hosting env; if you need or wish to add way more at every run, please leave a comment down below and there is a quick way to increase this to up to 21,000 domains per run -and if you need more than this, then you will need a queue system, and that means taking your domaining server to the next level by going to the cloud, watch for an upcoming series on the ultimate domaining server ).

And in Part VI we will be creating a user dashboard, that will allow you to monitor your domains easily, with real live stats directly from the webserver!

I hope you find this useful and thanks for reading,

s

 

 

 

 

 

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz

%d bloggers like this: