Status
Not open for further replies.

MattDees

Well-Known Member
Apr 29, 2005
416
1
243
Houston, TX
cPanel Access Level
Root Administrator
I've spent the past few weeks working on re-writing the XML-API PHP class, this is done taking lessons learned from the original one to write it in a much easier to use, fully-documented format. Within the new class, we have quite a few new features (and full backwards-compatibility with the old version.

I have also incorporated some of the features from the versions posted to the previous thread on the XML-API PHP Class. Thanks to all of y'all that have given feedback on this class/providing patches/etc it really is appreciated as it helps speed up development. Also I owe thanks to xenomedia and klaude from softlayer for helping with the development of this class.

New Features:

Added in 11.25 functions
Changed the constructor to allow for either the "DEFINE" config setting method or using parameters
Removed used of the gui setting
Added fopen support
Added auto detection for fopen or curl (uses curl by default)
Added ability to return in multiple formats: associative array, simplexml, xml, json
Added PHP Documentor documentation for all necessary functions
Changed submission from GET to POST
Change api1 and api2 query to use XML-API fast mode
added authentication failure detection for 11.24
add array checking where array parameters are taken in

This has been under internal review for a few days now and I feel that it is fleshed out to a point where it is ready for release. Another thing that we are working on is fully testing this class along with our product testing so that we can ensure that this works properly

URL is at the bottom of this post.


it should also be noted that there is full documentation on this class, look at the docs/ directory in the tarball (it's also pretty well documented in the code)



Original post (stealing for the sake of documentation):

A basic explanation of how to use this should be obvious from the example scripts attached, however I will go over what this is capable of:

All xml-api functions are implemented in this, provided with an easy interface:

f.ex:
Code:
$xmlapi->listaccts() can be used to list accounts
Some functions are called with normal arguments:

f.ex:
Code:
$xmlapi->addip($ip,$netmask)
On top of this, some functions require associative arrays (hashes) to be passed to them:

Code:
$acct = array( username => "someuser", password => "pass123", domain => "thisdomain.com");
$xmlapi->createacct($acct);

When instantiating this class it needs to call both the constructor and an authenticator function. This class support both password authentication and hash authentication, called via password_auth(user,pass) and hash_auth(user,authhash) respectively.

f.ex with hash auth.
Code:
$xmlapi = new xmlapi($ip);
$xmlapi->hash_auth("root",$root_hash);
f.ex. with password auth.
Code:
$xmlapi = new xmlapi($ip);
$xmlapi->password_auth("root",$root_pass);
Another feature is that this object can generate the API1 and API2 code automatically:

f.ex.
Code:
print $xmlapi->api1_query($account, "Email", "addpop", array($email_user, $email_password, $email_domain) );
Along with this, some debugging functions are provided with a simple boolean interface.

The first of these is set_debug which will show all URLs generated, API1/API2 XML and responses in XML and SimpleXML formats:

f.ex. call
Code:
$xmlapi->set_debug(1);
$xmlapi->listips();
will result in an output similar to:
Code:
QUERY:
https://127.0.0.1:2087/xml-api/listips?

RAW XML:

<listips>
  <result>
    <active>1</active>
    <if>eth1</if>
    <ip>127.0.0.1</ip>
    <mainaddr>1</mainaddr>
    <removable>0</removable>
    <used>1</used>
  </result>
  <result>
    <active>1</active>
    <if>eth1:1</if>
    <ip>127.0.0.2</ip>
    <mainaddr>0</mainaddr>
    <removable>0</removable>
    <used>1</used>
  </result>
  <result>
    <active>1</active>
    <if>eth1:3</if>
    <ip>127.0.0.3</ip>
    <mainaddr>0</mainaddr>
    <removable>1</removable>
    <used>0</used>
  </result>
  <result>
    <active>1</active>
    <if>eth1:4</if>
    <ip>127.0.0.4</ip>
    <mainaddr>0</mainaddr>
    <removable>1</removable>
    <used>0</used>
  </result>
</listips>

<!-- Web Host Manager  (c) cPanel, Inc. 2008 http://cpanel.net/  Unauthorized copying is prohibited. -->


object(SimpleXMLElement)#2 (1) {
  ["result"]=>
  array(4) {
    [0]=>
    object(SimpleXMLElement)#3 (6) {
      ["active"]=>
      string(1) "1"
      ["if"]=>
      string(4) "eth1"
      ["ip"]=>
      string(14) "127.0.0.1"
      ["mainaddr"]=>
      string(1) "1"
      ["removable"]=>
      string(1) "0"
      ["used"]=>
      string(1) "1"
    }
    [1]=>
    object(SimpleXMLElement)#4 (6) {
      ["active"]=>
      string(1) "1"
      ["if"]=>
      string(6) "eth1:1"
      ["ip"]=>
      string(14) "127.0.0.2"
      ["mainaddr"]=>
      string(1) "0"
      ["removable"]=>
      string(1) "0"
      ["used"]=>
      string(1) "1"
    }
    [2]=>
    object(SimpleXMLElement)#5 (6) {
      ["active"]=>
      string(1) "1"
      ["if"]=>
      string(6) "eth1:3"
      ["ip"]=>
      string(14) "127.0.0.3"
      ["mainaddr"]=>
      string(1) "0"
      ["removable"]=>
      string(1) "1"
      ["used"]=>
      string(1) "0"
    }
    [3]=>
    object(SimpleXMLElement)#6 (6) {
      ["active"]=>
      string(1) "1"
      ["if"]=>
      string(6) "eth1:4"
      ["ip"]=>
      string(14) "127.0.0.4"
      ["mainaddr"]=>
      string(1) "0"
      ["removable"]=>
      string(1) "1"
      ["used"]=>
      string(1) "0"
    }
  }
}
There is also a return_xml object that will just return the XML as a string rather than a SimpleXML object.


EDIT:

Patched for version 1.0.5.

There are a couple of fixes.

http://sdk.cpanel.net/lib/xmlapi/php/cp_xmlapi_php_v1.0.7.tar.gz

Changelog:
* 1.0.6:
* Changed 'user' URL parameter for API1/2 calls to 'cpanel_xmlapi_user'/'cpanel_jsonapi_user' to resolve conflicts with API2 functions that use 'user' as a parameter
* Relocated exmaple script to Example subdirectory
* Modified example scripts to take remote server IP and root password from environment variables REMOTE_HOST and REMOTE_PASSWORD, respectively
* Created subdirectory Tests for PHPUnit tests
* Add PHPUnit test BasicParseTest.php
*
* 1.0.5:
* fix bug where api1_query and api2_query would not return JSON data
*
* 1.0.4:
* set_port will now convert non-int values to ints
*
* 1.0.3:
* Fixed issue with set_auth_type using incorrect logic for determining acceptable auth types
* Suppress non-UTF8 encoding when using curl
*
* 1.0.2:
* Increased curl buffer size to 128kb from 16kb
* Fix double encoding issue in terminateresellers()
*
* 1.0.1:
* Fixed use of wrong variable name in curl error checking
* adjust park() to use api2 rather than API1
 
Last edited:

Alan D.

Member
Nov 4, 2009
6
0
51
Hi

Great class.

I just noticing a few errors related to parked domains.

The first is that the class method passes in a keyed array and tries to index it using numeric indexes:

PHP:
$args['domain'] = $newdomain;
$args['topdomain'] = $topdomain;
return $this->api1_query($username, 'Park', 'park', $args);

// in api1_query
for ($int = 0; $int < count($args);  $int++) {
  $call['arg-' . $int] = $args[$int];
}

# $call['arg-0'] = NULL
These are getting parsed as NULL

My workaround was:

PHP:
$int = 0;
foreach ($args as $arg) {
  $call['arg-' . $int++] = $arg;
}
Secondly, is it an issue with the cPanel version that we are running that adding parked domains fails anyway. The SimpleXML dump is:

Code:
SimpleXMLElement Object
(
    [module] => Park
    [func] => park
    [type] => event
    [source] => module
    [apiversion] => 1
    [data] => SimpleXMLElement Object
        (
            [result] => Error from park wrapper: The following domain is not configured for this account: thinkfast.caignwebs.com.au.thinkfast.caignwebs.com.au: @Cpanel::DOMAINS=(thinkfast.caignwebs.com.au,plantfinder.info)

        )
)
The top level domain is being repeated twice for some reason (thinkfast.caignwebs.com.au)

There are no issues trying to unpark a domain, so it is not an authentication error.

We have the following: cPanel 11.24.5-R38506 - WHM 11.24.2 - X 3.9

Any help would be greatly appreciated.

Cheers

Alan
 
Last edited:

teamred

Member
Sep 24, 2009
5
0
51
I had same problem, and solved it removing top_domain from argument list. This seems to be bug in API, or its documentation, because in documentation it is stated that we need argument top_domain too.

Hope this will help you to solve your problem
 

XenomediaBV

Well-Known Member
Sep 3, 2009
60
0
56
The Netherlands
cPanel Access Level
Root Administrator
Matt,

Some comments in de xmlapi.php class need an update. f.e.:

// This API function displays a list of all parked domains for a specific user.
public function park($username, $newdomain, $topdomain) {

// This API function displays a list of all parked domains for a specific user.
public function unpark($username, $domain) {

;)

Overall... nice work! I can't wait for the cPanel 11.25 stable to find out what else will become available for this class :D
 

yanayun

Member
May 14, 2005
23
0
151
bugs on adddns and killdns must fix soon.

problem :
adddns with reseller user can't display in WHM reseller edit DNS
because dns was in root permission, not reselller permission.

killdns problem with reseller user can't delete dns bacause dns files with root permission.
 

cdgan78

Registered
Dec 7, 2009
1
0
51
API call to create MySQL DB

I'm trying the following but doesn't seems to work

PHP:
//create database
$xmlapi->api1_query($cpuser, "Mysql", "adddb", $newdb);
	
//create user
$xmlapi->api1_query($cpuser, "Mysql", "adduser", array('user' => $newuser,'pass'=>$newpass));
	
//add user to database
$xmlapi->api1_query($cpuser, "Mysql", "adduserdb", array('db' => $newdb, 'user'=>$newuser, 'SELECT INSERT UPDATE DELETE'));
Any tip to achieving this?

Thanks
 

maever

Active Member
Sep 26, 2005
31
0
156
There do seem to be some problems with the park/unpark features.

We run cPanel 11.24.5-R38506 - WHM 11.24.2 - X 3.9 (Release build).

Upon using the default park feature, I get the following data returned:

Code:
<?xml version="1.0" ?>
<cpanelresult><module>Park</module><func>park</func><type>event</type><source>module</source><apiversion>1</apiversion><data><result>domain not specified</result></data></cpanelresult>
function is used as so:
Code:
echo $xmlapi->park( 'trac1', 'domain1.com', 'topdomain.com');
All normal features such as accountlisting seem to work correctly thus ruling out an authentication problem.

Using unpark (both with reseller and the user itself) results in this error:
Code:
<?xml version="1.0" ?>
<cpanelresult><module>Park</module><func>unpark</func><type>event</type><source>module</source><apiversion>1</apiversion><data><result>Error from park wrapper: Sorry, you do not control the domain 
</result></data></cpanelresult>

we have tried the instructions above and removed the topdomain from the function, the same error keeps appearing.


Anyone got an Idea what we're doing wrong ?

I believe this to be a fault in the API.
 

MattDees

Well-Known Member
Apr 29, 2005
416
1
243
Houston, TX
cPanel Access Level
Root Administrator
I'm trying the following but doesn't seems to work

PHP:
//create database
$xmlapi->api1_query($cpuser, "Mysql", "adddb", $newdb);
	
//create user
$xmlapi->api1_query($cpuser, "Mysql", "adduser", array('user' => $newuser,'pass'=>$newpass));
	
//add user to database
$xmlapi->api1_query($cpuser, "Mysql", "adduserdb", array('db' => $newdb, 'user'=>$newuser, 'SELECT INSERT UPDATE DELETE'));
Any tip to achieving this?

Thanks
api1 api calls do not take associative arrays, rather they take ordered parameters. you will need to pass these in the order that they appear within the api docs. f.ex:

PHP:
$xmlapi->api1_query($cpuser, "Mysql", "adddb", array($newdb) );
$xmlapi->api1_query($cpuser, "Mysql", "adduser", array( $newuser, $newpass ) );
$xmlapi->api1_query($cpuser, "Mysql", "addusertodb" array($newdb, $newuser, 'SELECT INSERT UPDATE DELETE'  ));
 

Alan D.

Member
Nov 4, 2009
6
0
51
In relation to parking domains

I had same problem, and solved it removing top_domain from argument list. This seems to be bug in API, or its documentation, because in documentation it is stated that we need argument top_domain too.

Hope this will help you to solve your problem
Eg:
PHP:
  $args = array();
  $args['domain'] = $newdomain;
 // $args['topdomain'] = cpanel_xmlapi_adaptor_domain();
  $xml = $xmlapi->api2_query($account, "Park", "park", $args);
Thanks TeamRed, this worked perfectly. Much appreciated!

This was the missing step the was preventing us from fully automating remote Drupal installs.
 

maever

Active Member
Sep 26, 2005
31
0
156
Changing api1_query to api2_query fixed it for me,
Parking now works perfectly!

Topdomain apperently doesn't need to be specified.

so change:
PHP:
return $this->api1_query($username, 'Park', 'park', $args);
to:
PHP:
return $this->api2_query($username, 'Park', 'park', $args);
 

dol

Registered
PartnerNOC
Dec 3, 2009
3
0
51
Update and some features

I reviewed the XML API PHP Class and found and fixed some minor bugs and friction. I also added a new exception, if the login fails. This works for curl and fopen.
Can someone test my edits with the CPanel Version 11.25. At the moment, I could only test 11.24.
 

Attachments

Last edited:

Smuxinho

Member
Jun 18, 2006
5
0
151
Hi
I try to use this api with call cpanel functions but I don't have success.
For example, I need to show what databases my customer have's already:

Code:
<?
include("xmlapi.php.inc");

$xmlapi = new xmlapi("myipaddress");
$xmlapi->password_auth("root","myuserpassword");
$xmlapi->set_debug(1);

print $xmlapi->api1_query("mycustomer", "Mysql", "listdbs", "");

?>
I receive the RAW XML, but not objects show this errors:
arning: simplexml_load_string(): Entity: line 2: parser error : AttValue: " or ' expected in /usr/local/apache/htdocs/APIs/2010/xmlapi.php.inc on line 104

Warning: simplexml_load_string(): f="deldb.html?db=mycustomer_apps"><img src="/frontend/x/images/delete.jpg" border= in /usr/local/apache/htdocs/APIs/2010/xmlapi.php.inc on line 104

Warning: simplexml_load_string(): ^ in /usr/local/apache/htdocs/APIs/2010/xmlapi.php.inc on line 104

Warning: simplexml_load_string(): Entity: line 2: parser error : attributes construct error in /usr/local/apache/htdocs/APIs/2010/xmlapi.php.inc on line 104


Anyone knows how I do to show this databases?
 

SolutionsPal

Registered
Aug 17, 2009
1
0
51
Any call I make using api1 or api2 I get something like this:

Code:
<br />
<b>Fatal error</b>:  Uncaught exception 'Exception' with message 'curl_exec threw error &quot;read function returned funny value&quot; for ?' in /home/myaccount/public_html/api/xmlapi.php:672
Stack trace:
#0 /home/myaccount/public_html/api/xmlapi.php(600): xmlapi-&gt;curl_query('https://127.0.0...', '', 'Authorization: ...')
#1 /home/myaccount/public_html/api/xmlapi.php(896): xmlapi-&gt;xmlapi_query('listaccts')
#2 /home/myaccount/public_html/api/api2_example.php(16): xmlapi-&gt;listaccts()
#3 {main}
  thrown in <b>/home/myaccount/public_html/api/xmlapi.php</b> on line <b>672</b><br />
when I call the create email, it actually creates the emails. but still get the same message above. I believe its with the feedback.

How to fix?

this is the content of api2_example.php:

PHP:
<?php

include("xmlapi.php");

$ip = "127.0.0.1";
$root_pass = "aaaaaaaaaaaaaa";
$account = "xxxxx";

$xmlapi = new xmlapi($ip);
$xmlapi->password_auth("root",$root_pass);

$xmlapi->set_debug(1);

print $xmlapi->listaccts();

?>


I would like to use the list account functions and get the accounts back.
 

MattDees

Well-Known Member
Apr 29, 2005
416
1
243
Houston, TX
cPanel Access Level
Root Administrator
I've encountered that issue before and have not been able to find a solution other than switching to fopen for handling.

No clue why curl on some systems fails like that :-/
 

dol

Registered
PartnerNOC
Dec 3, 2009
3
0
51
According to this original curl file ( [curl] Contents of /lib/transfer.c ), the error means, that the size for the read is bigger than the buffersize (it has to do with the upload size?!). I guess you add an curl curl_setopt for 'CURLOPT_BUFFERSIZE' to prevent this problem. Default buffer size is 16384bytes (16KB).
 

Smuxinho

Member
Jun 18, 2006
5
0
151
Hi again, this code don't work with me.

Code:
$xmlapi->api1_query($cpuser, "Mysql", "addusertodb" array($newdb, $newuser, 'USAGE'));
In RAW XML:
Code:
RAW API1 CALL:
<cpanelaction><module>Mysql</module><func>addusertodb</func><apiversion>1</apiversion><args>test</args><args>test</args></cpanelaction>
QUERY:
[url]https://...:2087/xml-api/cpanel?user=anyuser&xmlin=%3Ccpanelaction%3E%3Cmodule%3EMysql%3C%2Fmodule%3E%3Cfunc%3Eaddusertodb%3C%2Ffunc%3E%3Capiversion%3E1%3C%2Fapiversion%3E%3Cargs%3Etest%3C%2Fargs%3E%3Cargs%3Etest%3C%2Fargs%3E%3C%2Fcpanelaction%3E[/url]

RAW XML:

<?xml version="1.0" ?>
<cpanelresult><module>Mysql</module><func>addusertodb</func><type>event</type><source>internal</source><apiversion>1</apiversion><data><result></result></data>  <event>
    <result>1</result>
  </event>
</cpanelresult>


object(SimpleXMLElement)#3 (7) {
  ["module"]=>
  string(5) "Mysql"
  ["func"]=>
  string(11) "addusertodb"
  ["type"]=>
  string(5) "event"
  ["source"]=>
  string(8) "internal"
  ["apiversion"]=>
  string(1) "1"
  ["data"]=>
  object(SimpleXMLElement)#4 (1) {
    ["result"]=>
    object(SimpleXMLElement)#6 (0) {
    }
  }
  ["event"]=>
  object(SimpleXMLElement)#5 (1) {
    ["result"]=>
    string(1) "1"
  }
}
SIMPLEXML OBJ:
 
Last edited by a moderator:

anand

Well-Known Member
Nov 11, 2002
1,435
1
168
India
cPanel Access Level
DataCenter Provider
list accounts

Hi Matt,

I am trying to use listaccts to get a list of all domains. Can i somehow get only the list of domains and no other information ? Right now all the domain details are being returned which are causing problems to parse for me.

Any ideas ?
 
Status
Not open for further replies.