I'm creating a Perl plugin for cPanel which has to get all domains in the account of a user and display it in a HTML select
field. Originally, I'm a PHP developer, so I'm having a hard time understanding some of the logic of Perl. I do know that cPanel plugins can also be written in PHP, but for this plugin I'm limited to Perl.
This is how I get the data from cPanel:
my @user_domains = $cpliveapi->uapi('DomainInfo', 'list_domains');
@user_domains = $user_domains[0]{cpanelresult}{result}{data};
This is what it looks like using print Dumper @user_domains
:
$VAR1 = {
'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
'main_domain' => 'main-domain.com',
'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com']
};
I want the data to look like this (thanks @simbabque):
@domains = qw(domain1.com domain2.com domain3.com main-domain.com parked1.com parked2.com parked3.com);
So, I want to exclude sub_domains
and merge the others in 1 single-dimensional array so I can loop through them with a single loop. I've struggled the past few days with what sounds like an extremely simple task, but I just can't wrap my head around it.
That isn't doing what you think it' doing. {}
is the anonymous hash constructor, so you're making a 1 element array, with a hash in it.
You probably want:
use Data::Dumper;
my %user_domains = (
'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
'main_domain' => 'main-domain.com',
'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com'],
);
print Dumper \%user_domains;
And at which point the 'other' array elements you can iterate through either a double loop:
foreach my $key ( keys %user_domains ) {
if ( not ref $user_domains{$key} ) {
print $user_domains{$key},"\n";
next;
}
foreach my $domain ( @{$user_domains{$key}} ) {
print $domain,"\n";
}
}
Or if you really want to 'flatten' your hash:
my @flatten = map { ref $_ : @$_ ? $_ } values %user_domains;
print Dumper \@flatten;
(You need the ref
test, because without it, the non-array main-domain
won't work properly)
So for the sake of consistency, you might be better off with:
my %user_domains = (
'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
'main_domain' => ['main-domain.com'],
'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com'],
);
You need something like this
If you find you have a copy of List::Util
that doesn't include uniq
then you can either upgrade the module or use this definition
sub uniq {
my %seen;
grep { not $seen{$_}++ } @_;
}
From your dump, the uapi
call is returning a reference to a hash . That goes into $cp_response
and then drilling down into the structure fetches the data
hash reference into $data
delete
removes the subdomain information from the hash.
The lists you want are the values of the hash to which $data
refers, so I extract those. Those values are references to arrays of strings if there is more than one domain in the list, or simple strings if there is only one
The map
converts all the domain names to a single list by dereferencing array references, or passing strings straight through. That is what the ref() ? @$_ : $_
ref() ? @$_ : $_
is doing. FInally uniq
removes multiple occurrences of the same name
use List::Util 'uniq';
my $cp_response = $cpliveapi->uapi('DomainInfo', 'list_domains');
my $data = $cp_response->{cpanelresult}{result}{data};
delete $data->{sub_domains};
my @domains = uniq map { ref() ? @$_ : $_ } values %$data;
parked1.com
parked2.com
parked3.com
domain1.com
domain2.com
domain3.com
main-domain.com
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.