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&amp;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
-~----------~----~----~----~------~----~------~--~---

Reply via email to