title: Cakephp soap server
body: <p>I am trying to make a webservice in cakePHP 2, but all information I find is for cakePHP 1.
  I have done this after days of search but it doesn't work.
  I created the following controller : </p>
  
  <pre><code>class SoapsController extends AppController {
  
  var $components = array('RequestHandler');
  
  //listes des model utilisé
  public $uses =array('Pompe', 'Serie', 'Fluide','Control');
  
  function service() {
      $this-&gt;layout = false;
      $this-&gt;autoRender = false;
      Configure::write('debug', 0);
      ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
      $server = new SoapServer('http://localhost/pps/soaps/wsdl');
      $server-&gt;setClass("Soap");
      $server-&gt;handle();
  }
  
  function wsdl() {
      $this-&gt;layout = false;
      Configure::write('debug', 0);
      $this-&gt;RequestHandler-&gt;respondAs('xml');
  }
  }
  </code></pre>
  
  <p>And put the wsld file in view/soaps/wsdl.ctp.
  When I call the webservice with a client it doesn't work.
  Can you help me to do this?</p>
  
  <p><strong>After some try I change my code as follow but I have other error when I call webservice with a client</strong>
  I created a messagescontroller</p>
  
  <pre><code>class MessagesController extends AppController {
  
   public $uses = null; //for demostration purposes we do not need a model
  
  function beforeFilter(){
    parent::beforeFilter();
    $this-&gt;Auth-&gt;allow();
  
  }
  
      public $components = array(
          'Soap' =&gt; array(
              'wsdl' =&gt; 'myWSDLFile', //the file name in the view folder
              'action' =&gt; 'service', //soap service method / handler
          )
      );
  
      public function soap_wsdl(){
          //will be handled by SoapComponent
      }
  
      public function soap_service(){
          //will be handled by SoapComponent
      }
  
      /**
       * A soap call 'soap_foo' is handled here
       *
       * @param Object $in The input parameter 'foo'
       * @return Object
       */
      public function soap_foo($in){
          $obj = new stdClass();
          $obj-&gt;out = 'foo response';
          return $obj;
      }
  }
  </code></pre>
  
  <p>a file WSDL place in view/Elements/myWSDLFile.wsdl</p>
  
  <p>Create a messageModel</p>
  
  <pre><code>class Message extends AppModel {
      public $useTable = false; // Ce model n'utilise pas une table de la base de données
   }
  </code></pre>
  
  <p>add the class soapComponent in Controller/Component/SoapComponent.php</p>
  
  <pre><code>App::import('core', 'AppHelper');
  
  /**
  * Soap component for handling soap requests in Cake
  *
  * @author      Marcel Raaijmakers (Marcelius)
  * @copyright   Copyright 2009, Marcel Raaijmakers
  * @license     http://www.opensource.org/licenses/mit-license.php The MIT License
  */
  class SoapComponent extends Component{
  
      var $name = 'Soap';
  
      var $components = array('RequestHandler');
  
      var $controller;
  
      var $__settings = array(
          'wsdl' =&gt; false,
          'wsdlAction' =&gt; 'wsdl',
          'prefix' =&gt; 'soap',
          'action' =&gt; array('service'),
      );
  
      public function initialize($controller, $settings = array()){
          if (Configure::read('debug') != 0){
              ini_set('soap.wsdl_cache_enabled', false);
          }
  
          $this-&gt;controller = $controller;
  
          if (isset($settings['wsdl']) &amp;&amp; !empty($settings['wsdl'])){
              $this-&gt;__settings['wsdl'] = $settings['wsdl'];
          }
  
          if (isset($settings['prefix'])){
              $this-&gt;__settings['prefix'] = $settings['prefix'];
          }
  
          if (isset($settings['action'])){
              $this-&gt;__settings['action'] = is_array($settings['action']) ? $settings['action'] : array($settings['action']);
          }
  
          parent::initialize($controller);
      }
  
  
      public function startup(){
          if (isset($this-&gt;controller-&gt;params['soap'])){
              if ($this-&gt;__settings['wsdl'] != false){
                  //render the wsdl file
                  if ($this-&gt;action() == $this-&gt;__settings['wsdlAction']){
                      Configure::write('debug', 0);
                      $this-&gt;RequestHandler-&gt;respondAs('xml');
  
                      $this-&gt;controller-&gt;ext = '.wsdl';
                      $this-&gt;controller-&gt;render(null, false, DS . 'elements' . DS . $this-&gt;__settings['wsdl']); //only works with short open tags set to false!
                  } elseif(in_array($this-&gt;action(), $this-&gt;__settings['action'])) {
  
                      //handle request
                      $soapServer = new SoapServer($this-&gt;wsdlUrl());
                      $soapServer-&gt;setObject($this-&gt;controller);
                      $soapServer-&gt;handle();
  
                      //stop script execution
                      $this-&gt;_stop();
                      return false;
  
                  }
              }
          }
      }
  
      /**
       * Return the current action
       *
       * @return string
       */
      public function action(){
          return (!empty($this-&gt;__settings['prefix'])) ? str_replace( $this-&gt;__settings['prefix'] . '_', '',  $this-&gt;controller-&gt;action) : $this-&gt;controller-&gt;action;
      }
  
      /**
       * Return the url to the wsdl file
       *
       * @return string
       */
      public function wsdlUrl(){
          return AppHelper::url(array('controller'=&gt;Inflector::underscore($this-&gt;controller-&gt;name), 'action'=&gt;$this-&gt;__settings['wsdlAction'], $this-&gt;__settings['prefix'] =&gt; true), true);
      }
  
  }
  </code></pre>
  
  <p>And at the end change the routes file by adding</p>
  
  <pre><code>Router::connect('/soap/:controller/:action/*', array('prefix'=&gt;'soap', 'soap'=&gt;true));
  </code></pre>
  
  <p>And when I try using my web service with the client as follow </p>
  
  <pre><code>&lt;?php 
  ini_set('soap.wsdl_cache_enabled', 0); //enable when in production mode, this does save a lot of        time 
  
  $soapClient = new SoapClient('http://localhost/pps-soap/soap/messages/wsdl'); 
  
  $param = new StdClass(); 
  $param-&gt;in = 'param'; 
  
  $foo = $soapClient-&gt;soap_foo($param); 
  var_dump($foo); //an object of StdClass with an 'out' field and the value 'foo response' 
  ?&gt; 
  </code></pre>
  
  <p>I have a soap error that PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from
      <code>'http://localhost/pps-soap/soap/messages/wsdl'</code>
  I'm jsut totally lost!! Need help</p>