/** * Run the PHP SoapServer * * @param string $wsdlFile The WSDL file name or NULL to let PhpWsdl decide (default: NULL) * @param string|object|array $class The class name to serve, the classname and class as array or NULL (default: NULL) * @param boolean $andExit Exit after running the server? (default: TRUE) * @param boolean $forceNoWsdl Force no WSDL usage? (default: FALSE); * @return boolean Did the server run? */ public function RunServer($wsdlFile = null, $class = null, $andExit = true, $forceNoWsdl = false) { self::Debug('Run the server'); if ($forceNoWsdl) { self::Debug('Forced non-WSDL mode'); } if (self::CallHook('BeforeRunServerHook', array('server' => $this, 'wsdlfile' => &$wsdlFile, 'class' => &$class, 'andexit' => &$andExit, 'forcenowsdl' => &$forceNoWsdl))) { // WSDL requested? if ($this->OutputWsdlOnRequest($andExit)) { return false; } // PHP requested? if ($this->OutputPhpOnRequest($andExit)) { return false; } // HTML requested? if ($this->OutputHtmlOnRequest($andExit)) { return false; } } // Login $user = null; $password = null; if ($this->RequireLogin) { if (isset($_SERVER['PHP_AUTH_USER']) || isset($_SERVER['PHP_AUTH_PW'])) { $user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null; $password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null; } self::Debug('Check login ' . $user . ':' . str_repeat('*', strlen($password))); if (!self::CallHook('LoginHook', array('server' => $this, 'user' => &$user, 'password' => &$password))) { self::Debug('Login required'); header('WWW-Authenticate: Basic realm="SOAP webservice login required"'); header('HTTP/1.0 401 Unauthorized'); if ($andExit) { self::Debug('Exit script execution'); exit; } return false; } } // Load the proxy $useProxy = false; if (is_array($class)) { self::Debug('Use the proxy for ' . $class[0]); self::$ProxyObject = $class[1]; self::$ProxyServer = $this; $class = $class[0]; $useProxy = true; } // Ensure a webservice name if (is_null($class)) { self::Debug('No webservice name yet'); if (!$this->DetermineConfiguration()) { throw new Exception('Invalid configuration'); } if (!is_null($this->Name)) { $class = $this->Name; } } else { if (is_string($class)) { self::Debug('Using ' . $class . ' as webservice name'); $this->Name = $class; } } self::Debug('Use class ' . (!is_object($class) ? $class : get_class($class))); // Load WSDL if (!$forceNoWsdl && (!$useProxy || self::$UseProxyWsdl)) { self::Debug('Load WSDL'); $this->CreateWsdl(false, true); if (is_null($wsdlFile)) { $wsdlFile = $this->GetCacheFileName(); } if (!is_null($wsdlFile)) { if (!file_exists($wsdlFile)) { self::Debug('WSDL file "' . $wsdlFile . '" does not exists'); $wsdlFile = null; } } } // Load the files, if the webservice handler class doesn't exist if (!is_object($class)) { if (!class_exists($class) && !$this->IsOnlyGlobal()) { self::Debug('Try to load the webservice handler class'); $i = -1; $len = sizeof($this->Files); while (++$i < $len) { self::Debug('Load ' . $this->Files[$i]); require_once $this->Files[$i]; } if (!class_exists($class)) { // Try class.webservice.php if (file_exists('class.webservice.php')) { self::Debug('Try to load class.webservice.php'); require_once 'class.webservice.php'; if (class_exists($class)) { $this->Files[] = 'class.webservice.php'; } } if (!class_exists($class)) { if (file_exists(dirname(__FILE__) . '/class.webservice.php')) { self::Debug('Try to load ' . dirname(__FILE__) . '/class.webservice.php'); require_once dirname(__FILE__) . '/class.webservice.php'; if (class_exists($class)) { $this->Files[] = dirname(__FILE__) . '/class.webservice.php'; } } } if (!class_exists($class)) { // A handler class or object is required when using non-global methods! throw new Exception('Webservice handler class not present'); } } } } // Prepare the SOAP server $this->SoapServer = null; if (self::CallHook('PrepareServerHook', array('server' => $this, 'soapserver' => &$this->SoapServer, 'wsdlfile' => &$wsdlFile, 'class' => &$class, 'useproxy' => &$useProxy, 'forcenowsdl' => &$forceNoWsdl, 'andexit' => &$andExit, 'user' => &$user, 'password' => &$password))) { self::Debug('Prepare the SOAP server'); // WSDL file $wsdlFile = $forceNoWsdl || $useProxy && !self::$UseProxyWsdl ? null : $wsdlFile; if (!is_null($wsdlFile)) { self::Debug('Using WSDL file ' . $wsdlFile); } else { self::Debug('No WSDL file'); } // Server options $temp = array('actor' => $this->EndPoint, 'uri' => $this->NameSpace); $temp = array_merge($this->SoapServerOptions, $temp); if (self::$Debugging) { self::Debug('Server options: ' . print_r($temp, true)); } // Create the server object self::Debug('Creating PHP SoapServer object'); $this->SoapServer = new SoapServer($wsdlFile, $temp); // Set the handler class or object if ($useProxy || !is_object($class)) { $temp = $useProxy ? 'PhpWsdlProxy' : $class; if (!is_null($temp)) { self::Debug('Setting server class ' . $temp); $this->SoapServer->setClass($temp); } else { self::Debug('No server class or object'); } } else { self::Debug('Setting server object ' . get_class($class)); $this->SoapServer->setObject($class); } // Add global methods $i = -1; $len = sizeof($this->Methods); while (++$i < $len) { if ($this->Methods[$i]->IsGlobal) { self::Debug('Adding global method ' . $this->Methods[$i]->Name); $this->SoapServer->addFunction($this->Methods[$i]->Name); } } } // Run the SOAP server if (self::CallHook('RunServerHook', array('server' => $this, 'soapserver' => &$this->SoapServer, 'wsdlfile' => &$wsdlFile, 'class' => &$class, 'useproxy' => &$useProxy, 'forcenowsdl' => &$forceNoWsdl, 'andexit' => &$andExit, 'user' => &$user, 'password' => &$password))) { self::Debug('Run the SOAP server'); $this->SoapServer->handle(); if ($andExit) { self::Debug('Exit script execution'); exit; } } return true; }