Version: current

      1 <?php
      2 /**
      3  * Basic SOAP Server to access and modify DataObject instances.
      4  * You can enable SOAP access on a DataObject by setting {@link DataObject::$api_access} to true.
      5  * This means that you'll also enable a RESTful API through {@link RestfulServer}.
      6  *
      7  * Usage - Getting a record:
      8  * <code>
      9  * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
     10  * echo $c->getXML("MyClassName", 99); // gets record #99 as xml
     11  * </code>
     12  *
     13  * Usage - Updating a record:
     14  * <code>
     15  * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
     16  * $data = array('MyProperty' => 'MyUpdatedValue');
     17  * echo $c->putXML("MyClassName", 99, null, $data);
     18  * </code>
     19  *
     20  * Usage - Creating a record:
     21  * <code>
     22  * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
     23  * $data = array('MyProperty' => 'MyValue');
     24  * echo $c->putXML("MyClassName", null, null, $data);
     25  * </code>
     26  *
     27  * Usage - Creating a record:
     28  * <code>
     29  * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
     30  * echo $c->deleteXML("MyClassName");
     31  * </code>
     32  *
     33  * @todo Test relation methods
     34  *
     35  * @package sapphire
     36  * @subpackage api
     37  */
     38 class SOAPModelAccess extends SapphireSoapServer {
     39
     40     public static $methods = array(
     41         'getXML' => array(
     42             'class' => 'string',
     43             'id' => 'int',
     44             'relation' => 'string',
     45             '_returns' => 'string',
     46         ),
     47         'getJSON' => array(
     48             'class' => 'string',
     49             'id' => 'int',
     50             'relation' => 'string',
     51             '_returns' => 'string',
     52         ),
     53         'putXML' => array(
     54             'class' => 'string',
     55             'id' => 'int',
     56             'relation' => 'string',
     57             'data' => 'string',
     58             'username' => 'string',
     59             'password' => 'string',
     60             '_returns' => 'boolean',
     61         ),
     62         'putJSON' => array(
     63             'class' => 'string',
     64             'id' => 'int',
     65             'relation' => 'string',
     66             '_returns' => 'boolean',
     67         ),
     68     );
     69
     70     function Link($action = null) {
     71         return Controller::join_links("soap/v1/", $action);
     72     }
     73
     74     /**
     75      * Used to emulate RESTful GET requests with XML data.
     76      *
     77      * @param string $class
     78      * @param Number $id
     79      * @param string $relation Relation name
     80      * @return string
     81      */
     82     function getXML($class, $id, $relation = false, $username = null, $password = null) {
     83         $this->authenticate($username, $password);
     84
     85         $response = Director::test(
     86             $this->buildRestfulURL($class, $id, $relation, 'xml'),
     87             null,
     88             null,
     89             'GET'
     90         );
     91
     92         return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
     93     }
     94
     95     /**
     96      * Used to emulate RESTful GET requests with JSON data.
     97      *
     98      * @param string $class
     99      * @param Number $id
    100      * @param string $relation Relation name
    101      * @param string $username
    102      * @param string $password
    103      * @return string
    104      */
    105     function getJSON($class, $id, $relation = false, $username = null, $password = null) {
    106         $this->authenticate($username, $password);
    107
    108         $response = Director::test(
    109             $this->buildRestfulURL($class, $id, $relation, 'json'),
    110             null,
    111             null,
    112             'GET'
    113         );
    114
    115         return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
    116     }
    117
    118     /**
    119      * Used to emulate RESTful POST and PUT requests with XML data.
    120      *
    121      * @param string $class
    122      * @param Number $id
    123      * @param string $relation Relation name
    124      * @param array $data
    125      * @param string $username
    126      * @param string $password
    127      * @return string
    128      */
    129     function putXML($class, $id = false, $relation = false, $data, $username = null, $password = null) {
    130         $this->authenticate($username, $password);
    131
    132         $response = Director::test(
    133             $this->buildRestfulURL($class, $id, $relation, 'xml'),
    134             array(),
    135             null,
    136             ($id) ? 'PUT' : 'POST',
    137             $data
    138         );
    139
    140         return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
    141     }
    142
    143     /**
    144      * Used to emulate RESTful POST and PUT requests with JSON data.
    145      *
    146      * @param string $class
    147      * @param Number $id
    148      * @param string $relation Relation name
    149      * @param array $data
    150      * @param string $username
    151      * @param string $password
    152      * @return string
    153      */
    154     function putJSON($class = false, $id = false, $relation = false, $data, $username = null, $password = null) {
    155         $this->authenticate($username, $password);
    156
    157         $response = Director::test(
    158             $this->buildRestfulURL($class, $id, $relation, 'json'),
    159             array(),
    160             null,
    161             ($id) ? 'PUT' : 'POST',
    162             $data
    163         );
    164
    165         return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
    166     }
    167
    168     /**
    169      * Used to emulate RESTful DELETE requests.
    170      *
    171      * @param string $class
    172      * @param Number $id
    173      * @param string $relation Relation name
    174      * @param string $username
    175      * @param string $password
    176      * @return string
    177      */
    178     function deleteXML($class, $id, $relation = false, $username = null, $password = null) {
    179         $this->authenticate($username, $password);
    180
    181         $response = Director::test(
    182             $this->buildRestfulURL($class, $id, $relation, 'xml'),
    183             null,
    184             null,
    185             'DELETE'
    186         );
    187
    188         return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
    189     }
    190
    191     /**
    192      * Used to emulate RESTful DELETE requests.
    193      *
    194      * @param string $class
    195      * @param Number $id
    196      * @param string $relation Relation name
    197      * @param string $username
    198      * @param string $password
    199      * @return string
    200      */
    201     function deleteJSON($class, $id, $relation = false, $username = null, $password = null) {
    202         $this->authenticate($username, $password);
    203
    204         $response = Director::test(
    205             $this->buildRestfulURL($class, $id, $relation, 'json'),
    206             null,
    207             null,
    208             'DELETE'
    209         );
    210
    211         return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
    212     }
    213
    214     /**
    215      * Faking an HTTP Basicauth login in the PHP environment
    216      * that RestfulServer can pick up.
    217      *
    218      * @param string $username Username
    219      * @param string $password Plaintext password
    220      */
    221     protected function authenticate($username, $password) {
    222         if(is_string($username)) $_SERVER['PHP_AUTH_USER'] = $username;
    223         if(is_string($password)) $_SERVER['PHP_AUTH_PW'] = $password;
    224     }
    225
    226     /**
    227      * @param string $class
    228      * @param Number $id
    229      * @param string $relation
    230      * @param string $extension
    231      * @return string
    232      */
    233     protected function buildRestfulURL($class, $id, $relation, $extension) {
    234        $url = "api/v1/{$class}";
    235        if($id) $url .= "/{$id}";
    236        if($relation) $url .= "/{$relation}";
    237        if($extension) $url .= "/.{$extension}";
    238        return $url;
    239     }
    240
    241     /**
    242      * @param SS_HTTPResponse $response
    243      * @return string XML string containing the HTTP error message
    244      */
    245     protected function getErrorMessage($response) {
    246         return "<error type=\"authentication\" code=\"" . $response->getStatusCode() . "\">" . $response->getStatusDescription() . "</error>";
    247     }
    248 }
    249
    250 ?>

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -