The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

XML API PHP Class version 1.0

Discussion in 'cPanel Developers' started by MattDees, Oct 28, 2009.

Thread Status:
Not open for further replies.
  1. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    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
     
    #1 MattDees, Oct 28, 2009
    Last edited: Aug 12, 2010
  2. Alan D.

    Alan D. Member

    Joined:
    Nov 4, 2009
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    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
     
    #2 Alan D., Nov 4, 2009
    Last edited: Nov 4, 2009
  3. teamred

    teamred Member

    Joined:
    Sep 24, 2009
    Messages:
    5
    Likes Received:
    0
    Trophy Points:
    1
    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
     
  4. XenomediaBV

    XenomediaBV Well-Known Member

    Joined:
    Sep 3, 2009
    Messages:
    60
    Likes Received:
    0
    Trophy Points:
    6
    Location:
    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
     
  5. yanayun

    yanayun Member

    Joined:
    May 14, 2005
    Messages:
    22
    Likes Received:
    0
    Trophy Points:
    1
    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.
     
  6. cdgan78

    cdgan78 Registered

    Joined:
    Dec 7, 2009
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    1
    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
     
  7. maever

    maever Active Member

    Joined:
    Sep 26, 2005
    Messages:
    38
    Likes Received:
    0
    Trophy Points:
    6
    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.
     
  8. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    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'  ));
     
  9. Alan D.

    Alan D. Member

    Joined:
    Nov 4, 2009
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    In relation to parking domains

    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.
     
  10. maever

    maever Active Member

    Joined:
    Sep 26, 2005
    Messages:
    38
    Likes Received:
    0
    Trophy Points:
    6
    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);
     
  11. dol

    dol Registered
    PartnerNOC

    Joined:
    Dec 3, 2009
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    1
    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.
     

    Attached Files:

    #11 dol, Dec 13, 2009
    Last edited: Dec 15, 2009
  12. Smuxinho

    Smuxinho Member

    Joined:
    Jun 18, 2006
    Messages:
    5
    Likes Received:
    0
    Trophy Points:
    1
    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?
     
  13. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    #13 MattDees, Dec 21, 2009
    Last edited: Dec 21, 2009
  14. Smuxinho

    Smuxinho Member

    Joined:
    Jun 18, 2006
    Messages:
    5
    Likes Received:
    0
    Trophy Points:
    1
    #14 Smuxinho, Dec 21, 2009
    Last edited: Dec 22, 2009
  15. SolutionsPal

    SolutionsPal Registered

    Joined:
    Aug 17, 2009
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    1
    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.
     
  16. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    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 :-/
     
  17. dol

    dol Registered
    PartnerNOC

    Joined:
    Dec 3, 2009
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    1
    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).
     
  18. Smuxinho

    Smuxinho Member

    Joined:
    Jun 18, 2006
    Messages:
    5
    Likes Received:
    0
    Trophy Points:
    1
    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:
    
    
    
    
    
     
    #18 Smuxinho, Dec 24, 2009
    Last edited by a moderator: Jan 4, 2010
  19. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    it's adduserdb not addusertodb

    see: MysqlRef < DeveloperResources/ApiRef < TWiki
     
  20. anand

    anand Well-Known Member

    Joined:
    Nov 11, 2002
    Messages:
    1,435
    Likes Received:
    1
    Trophy Points:
    38
    Location:
    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 ?
     
Loading...
Thread Status:
Not open for further replies.

Share This Page