This has been tested with the version ( 1.0.0beta4 ), I had a bit different structure for older version.
Ok ... here we go... how to create a soap server and take advatage of symfony's models and actions.
First we need the soap environment file, this will be the file that will initiate the soap API environment and the soap server:
name: /web/soapapi.php (soap server)
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'fo'); define('SF_ENVIRONMENT', 'soap'); define('SF_DEBUG', true); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); ini_set("soap.wsdl_cache_enabled", "0"); $server = new SoapServer('http://www.example.com/soapapi.wsdl'); //this file is defined in the next step $server->setClass("mySoapController"); // more to come on this one $server->handle(); ?>
Now we need a wsdl file that will take advantage of the environment above.
name: /web/soapapi.wsdl (soap server definition)
<?xml version='1.0' encoding='UTF-8'?> <definitions name="soapapi" targetNamespace="urn:soapapi" xmlns:typens="urn:soapapi" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="getFactorial"> <part name="user" type="xsd:string">user name</part> <part name="password" type="xsd:string">user password</part> <part name="number" type="xsd:float">user password</part> </message> <message name="getFactorialResponse"> <part name="return" type="xsd:float"/> </message> <portType name="soapapiPortType"> <operation name="getFactorial"> <documentation> user required password required Generates the factorial of a passed number. </documentation> <input message="typens:getFactorial"/> <output message="typens:getFactorialResponse"/> </operation> </portType> <binding name="soapapiBinding" type="typens:soapapiPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getFactorial"> <soap:operation soapAction="urn:soapapiAction"/> <input> <soap:body namespace="urn:soapapi" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output> <soap:body namespace="urn:soapapi" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <service name="soapapiService"> <port name="soapapiPort" binding="typens:soapapiBinding"> <soap:address location="http://www.example.com/soapapi.php"/> </port> </service> </definitions>
Now we need to write our soap cotroller layer and that is the class that is asssigned by the soap server above.
name: /apps/fo/lib/mySoapController.class.php
<?php class mySoapController extends sfController { public $request; public function __construct(){ /** * Since we're bypassing Symfony's action dispatcher, we have to initialize manually. */ $this->context = sfContext::getInstance(); $this->request = $this->context->getRequest(); } protected function soapAuth($domain,$password){ try { $c = new Criteria(); $c->add(UserPeer::USERNAME ,$domain); $c->add(UserPeer::PASSWORD ,$password); $check = UserPeer::doSelectOne($c); if($check){ $user = $this->context->getUser(); $user->addCredential($check->getCredential()); $user->setAuthenticated(true); }else{ throw new Exception('Soap Authentication failed'); } }catch (Exception $e){ throw new SoapFault("1",$e->getMessage()); } } function getFactorial($user, $password, $number){ $this->soapAuth($user, $password); //I call this at the start of each function call in the soap controller (You can choose not to do it) $this->request->setParameter('number',$number); $action = $this->getAction('soapapi','getFactorial'); $result = $action->executeGetFactorial(); return $result; } } ?>
We are almost there ... Next we need action and view
name: /apps/fo/modules/soapapi/actions.class.php
<?php class soapapiActions extends sfActions { public function __construct(){ if(SF_ENVIRONMENT == 'soap') $this->initialize(sfContext::getInstance()); } public function executeIndex() { $this->forward('default', 'module'); } public function executeGetFactorial(){ $num = $this->getRequestParameter('number'); $result = 1; for($i=1;$i<$num;$i++) $result = $result + ($result * $i); if(SF_ENVIRONMENT == 'soap') return $result; //you can return the view or just a number... usually for soap you want to return simple stuff ... so you need to do the check $this->result = $result; } } ?>
finally the view...
name: /apps/fo/modules/soapapi/getFactorialSuccess.php
<?php echo "The factorial for ".$sf_params->get('number')." is {$result} "; ?>