I want to make SOAP service with WSDL generation like this http://bakery.cakephp.org/articles/view/a-component-to-help-creating-soap-services, but with handle by controller like this http://bakery.cakephp.org/articles/view/implementing-soap-on-cakephp. With authorization.
app/controllers/components/soap.php <?php vendor('wshelper/lib/soap/IPReflectionClass.class'); vendor('wshelper/lib/soap/IPReflectionCommentParser.class'); vendor('wshelper/lib/soap/IPXMLSchema.class'); vendor('wshelper/lib/soap/IPReflectionMethod.class'); vendor('wshelper/lib/soap/WSDLStruct.class'); vendor('wshelper/lib/soap/WSDLException.class'); /** * Class SoapComponent * * Generate WSDL and handle SOAP calls */ class SoapComponent extends Component { var $params = array(); function initialize(&$controller) { $this->params = $controller->params; } /** * Get WSDL for specified model. * * @param string $modelClass : model name in camel case * @param string $serviceMethod : method of the controller that will handle SOAP calls */ function getWSDL($modelId, $serviceMethod = 'call') { $modelClass = $this->__getModelClass($modelId); $expireTime = '+1 year'; $cachePath = $modelClass . '.wsdl'; // Check cache if exist $wsdl = cache($cachePath, null, $expireTime); // If DEBUG > 0, compare cache modified time to model file modified time if ((Configure::read() > 0) && (! is_null($wsdl))) { $cacheFile = CACHE . $cachePath; if (is_file($cacheFile)) { $modelMtime = filemtime($this- >__getModelFile($modelId)); $cacheMtime = filemtime(CACHE . $cachePath); if ($modelMtime > $cacheMtime) { $wsdl = null; } } } // Generate WSDL if not cached if (is_null($wsdl)) { App::import('Controller',array($modelClass)); $refl = new IPReflectionClass($this- >__getFullNameClass($modelId)); $controllerName = $this->params['controller']; $serviceURL = Router::url("/$controllerName/ $serviceMethod", true); $wsdlStruct = new WSDLStruct('http:// schema.example.com', $serviceURL . '/' . $modelId, SOAP_RPC, SOAP_LITERAL); $wsdlStruct->setService($refl); try { $wsdl = $wsdlStruct->generateDocument(); // cache($cachePath, $wsdl, $expireTime); } catch (WSDLException $exception) { if (Configure::read() > 0) { $exception->Display(); exit(); } else { return null; } } } return $wsdl; } /** * Handle SOAP service call * * @param string $modelId : underscore notation of the called model * without _service ending * @param string $wsdlMethod : method of the controller that will generate the WSDL */ function handle($modelId, $wsdlMethod = 'wsdl') { $modelClass = $this->__getModelClass($modelId); $wsdlCacheFile = CACHE . $modelClass . '.wsdl'; // Try to create cache file if not exists if (! is_file($wsdlCacheFile)) { $this->getWSDL($modelId); } if (is_file($wsdlCacheFile)) { $server = new SoapServer($wsdlCacheFile); } else { $controllerName = $this->params['controller']; $wsdlURL = Router::url("/$controllerName/$wsdlMethod", true); $server = new SoapServer($wsdlURL . '/' . $modelId); } //$server->setClass($modelClass."Controller"); $server->setClass($controllerName.'Controller'); $server->handle(); } /** * Get model class for specified model id * * @access private * @return string : the model id */ function __getModelClass($modelId) { $inflector = new Inflector; return ($inflector->camelize($modelId) . 'service'); } function __getFullNameClass($modelId) { $inflector = new Inflector; return ($inflector->camelize($modelId) . 'serviceController'); } /** * Get model file for specified model id * * @access private * @return string : the filename */ function __getModelFile($modelId) { $modelDir = dirname(dirname(dirname(__FILE__))) . DS . 'controllers'; return $modelDir . DS . $modelId . '_controller.php'; } } ?> app/controllers/service_controller.php <?php class ServiceController extends AppController { public $name = 'Service'; public $uses = array(); public $helpers = array(); public $components = array('Soap'); public function call() { CakeLog::write(LOG_DEBUG,'Begin worked with SOAP client ServiceController::call'); $this->autoRender = FALSE; $this->Soap->handle('order', 'wsdl'); } public function wsdl() { CakeLog::write(LOG_DEBUG,'generate WSDL for SOAP client'); $this->autoRender = FALSE; echo $this->Soap->getWSDL('order', 'call'); } public function __call ( $func_name, $args ){ CakeLog::write(LOG_DEBUG,'handle request in serviceController - '. $func_name); return $this->requestAction('/Orderservice'.'/'. $func_name.'/', array('pass'=>$args) ); } } ?> app/components/orderservice_controller.php <? class OrderserviceController extends AppController { public $name = 'Orderservice'; public $uses = array(); public $components = array('Orderr'); public $Orderr; /** * * @param string $xml * @return string */ public function addOrder($xml) { CakeLog::write(LOG_DEBUG,'called addorder in class orderserviceController '); $this->autoRender = false; } /** * * @param string $username * @param string $password * @return string */ protected function UsernameToken( $username, $password ){ CakeLog::write(LOG_DEBUG,'called UsernameToken in class orderserviceController '); } } ?> Client. Get from http://php.oregonstate.edu/manual/en/function.soap-soapserver-construct.php class SoapHeaderUsernameToken { /** @var int Password */ public $Password; /** @var int Username */ public $Username; public function __construct($l, $p) { $this->Password = $p; $this->Username = $l; } } $client = new SoapClient('http://mm.ru/service/wsdl/', array('trace' => 1)); try { // Set the login headers $wsu = 'http://schemas.xmlsoap.org/ws/2002/07/utility'; $usernameToken = new SoapHeaderUsernameToken('root', 'pass'); $soapHeaders[] = new SoapHeader($wsu, 'UsernameToken', $usernameToken); $client->__setSoapHeaders($soapHeaders); $result = $client->addOrder($xml); } catch (SoapFault $fault) { var_dump($fault); } echo "REQUEST:\n" . $client->__getLastRequest() . "\n"; echo "RESPONSE:\n" . $client->__getLastResponse() . "\n"; Authorization method UsernameToken is not called and i don't know why. Trace. REQUEST: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/ envelope/" xmlns:ns1="http://schema.example.com" xmlns:ns2="http:// schemas.xmlsoap.org/ws/2002/07/utility"> <SOAP-ENV:Header> ns2:UsernameToken> <Password>pass</Password> <Username>root</Username> </ns2:UsernameToken> </SOAP-ENV:Header> <SOAP-ENV:Body><ns1:addOrder><xml>tra la la</xml> </ns1:addOrder> </SOAP-ENV:Body> </SOAP-ENV:Envelope> RESPONSE: <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/ envelope/" xmlns:ns1="http://schema.example.com"> <SOAP-ENV:Body> <ns1:addOrderResponse><addOrderReturn/> </ns1:addOrderResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> In logs: Debug: generate WSDL for SOAP client Debug: Begin worked with SOAP client ServiceController::call Debug: handle request in serviceController - addOrder Debug: called addorder in class orderserviceController WSDL: <?xml version="1.0"?> <wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP- ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http:// schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/ XMLSchema" xmlns:tns="http://schema.example.com" targetNamespace="http://schema.example.com"><wsdl:types><xsd:schema targetNamespace="http://schema.example.com"/></wsdl:types><message name="addOrderRequest"><part name="xml" type="xsd:string"/></ message><message name="addOrderResponse"><part name="addOrderReturn" type="xsd:string"/></message><wsdl:portType name="OrderserviceControllerPortType"><wsdl:operation name="addOrder"><wsdl:input message="tns:addOrderRequest"/ ><wsdl:output message="tns:addOrderResponse"/></wsdl:operation></ wsdl:portType><binding name="OrderserviceControllerBinding" type="tns:OrderserviceControllerPortType"><soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="addOrder"><soap:operation soapAction="http://mm.ru/service/call/ order&method=addOrder" style="rpc"/><wsdl:input><soap:body use="literal" namespace="http://schema.example.com"/></ wsdl:input><wsdl:output><soap:body use="literal" namespace="http:// schema.example.com"/></wsdl:output></wsdl:operation></ binding><wsdl:service name="OrderserviceController"><wsdl:port name="OrderserviceControllerPort" binding="tns:OrderserviceControllerBinding"><soap:address location="http://mm.ru/service/call/order"/></wsdl:port></ wsdl:service></wsdl:definitions> <!-- 0.4944s --> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Cake PHP" group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~----------~----~----~----~------~----~------~--~---