Ticket #377: soapSupport.diff
| File soapSupport.diff, 16.6 kB (added by sylvain261, 9 months ago) |
|---|
-
../jelix/core/request/jSoapRequest.class.php
old new 1 <?php 2 /** 3 * @package jelix 4 * @subpackage core_request 5 * @author Sylvain de Vathaire 6 * @contributor 7 * @copyright 2008 Sylvain de Vathaire 8 * @link http://www.jelix.org 9 * @licence GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html 10 */ 11 12 /** 13 * handle a soap call. The response has to be a soap response. 14 * @package jelix 15 * @subpackage core_request 16 */ 17 class jSoapRequest extends jRequest { 18 19 public $type = 'soap'; 20 21 public $defaultResponseType = 'soap'; 22 23 public $soapMsg; 24 25 26 function __construct(){ } 27 28 /** 29 * Paramameters initalisation prior to request handling 30 */ 31 function initService(){ 32 33 if(isset($_GET["service"]) && $_GET['service'] != ''){ 34 list($module, $action) = explode('~',$_GET["service"]); 35 }else{ 36 throw new JException('jWSDL~errors.service.param.required'); 37 } 38 39 $this->params['module'] = $module; 40 $this->params['action'] = $action; 41 42 if(isset($HTTP_RAW_POST_DATA) && ($HTTP_RAW_POST_DATA!='')){ 43 $this->soapMsg = $HTTP_RAW_POST_DATA; 44 }else{ 45 $this->soapMsg = file("php://input"); 46 $this->soapMsg = implode(" ", $this->soapMsg); 47 } 48 49 $this->_initUrlData(); //Need to be called manually before coordinator call of init because needed for the WSDL generation 50 } 51 52 53 /** 54 * Overload of the init method to prevent calling twice _initUrlData 55 */ 56 function init(){} 57 58 protected function _initParams(){} 59 60 public function allowedResponses(){ 61 return array('jResponseSoap'); 62 } 63 64 } 65 ?> -
../jelix/core/response/jResponseSoap.class.php
old new 1 <?php 2 /** 3 * @package jelix 4 * @subpackage core_response 5 * @author Sylvain de Vathaire 6 * @contributor 7 * @copyright 2008 Sylvain de Vathaire 8 * @link http://www.jelix.org 9 * @licence GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html 10 */ 11 12 /** 13 * Response for soap web services 14 * @package jelix 15 * @subpackage core_response 16 * @see jResponse 17 */ 18 final class jResponseSoap extends jResponse { 19 /** 20 * @var string 21 */ 22 protected $_type = 'soap'; 23 protected $_acceptSeveralErrors=false; 24 25 /** 26 * PHP data you want to return 27 * @var mixed 28 */ 29 public $data = null; 30 31 32 public function output(){ 33 if($this->hasErrors()) return false; 34 return true; 35 } 36 37 public function outputErrors(){ 38 global $gJCoord, $gJConfig; 39 40 if(count($gJCoord->errorMessages)){ 41 $e = $gJCoord->errorMessages[0]; 42 $errorCode = $e[1]; 43 $errorMessage = '['.$e[0].'] '.$e[2].' (file: '.$e[3].', line: '.$e[4].')'; 44 }else{ 45 $errorMessage = 'Unknow error'; 46 $errorCode = -1; 47 } 48 49 //soapFault param have to be UTF-8 encoded (soapFault seems to not use the encoding param of the SoapServer) 50 if($gJConfig->charset != 'UTF-8'){ 51 $errorCode = utf8_encode($errorCode); 52 $errorMessage = utf8_encode($errorMessage); 53 } 54 $soapServer = $gJCoord->getSoapServer(); 55 $soapServer->fault($errorCode, $errorMessage); 56 } 57 } 58 ?> -
../jelix/core/jSoapCoordinator.class.php
old new 1 <?php 2 /** 3 * @package jelix 4 * @subpackage core 5 * @author Sylvain de Vathaire 6 * @copyright 2008 Sylvain DE VATHAIRE 7 * @link http://www.jelix.org 8 * @licence GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html 9 */ 10 11 12 /** 13 * jWSDL utility class 14 */ 15 require_once(JELIX_LIB_UTILS_PATH.'jWSDL.class.php'); 16 17 18 /** 19 * Specialisation of the main class of the jelix core for soap purpose 20 * 21 * @package jelix 22 * @subpackage core 23 * @see jCoordinator 24 */ 25 class jSoapCoordinator extends jCoordinator { 26 27 /** 28 * WSDL utility object 29 * @var jWSDL 30 */ 31 var $wsdl; 32 33 /** 34 * Soap server reference 35 * @var SoapServer 36 */ 37 var $soapServer; 38 39 /** 40 * Intercept the soapServer method call in order to handle the call thrue the process method 41 * Return php variables, the soap server will transform it in a soap response 42 */ 43 public function processSoap(){ 44 45 global $gJConfig; 46 47 $this->wsdl = new jWSDL($this->request->params['module'], $this->request->params['action']); 48 49 $this->soapServer = $this->getSoapServer($this->wsdl); 50 $this->soapServer->setclass('jSoapHandler', $this); 51 $this->soapServer->handle($this->request->soapMsg); 52 } 53 54 /** 55 * Init and return the soap server 56 * Use wsdl mode or not depending of the wsdl object param 57 $ param jWsdl $wsdl 58 */ 59 public function getSoapServer($wsdl = null){ 60 61 global $gJConfig; 62 63 if(is_null($this->soapServer)){ 64 if(is_null($wsdl)){ 65 $this->soapServer = new SoapServer(null, array('soap_version' => SOAP_1_1, 'encoding' => $gJConfig->charset, 'uri' => $_SERVER['PHP_SELF'])); 66 }else{ 67 $this->soapServer = new SoapServer($wsdl->getWSDLFilePath(), array('soap_version' => SOAP_1_1, 'encoding' => $gJConfig->charset)); 68 } 69 } 70 return $this->soapServer; 71 } 72 } 73 74 75 /** 76 * Handler for soap extension call 77 * @package jelix 78 * @subpackage core_response 79 */ 80 class jSoapHandler { 81 82 /** 83 * Coordinator 84 */ 85 var $jelix; 86 87 88 function __construct($jelix) { 89 $this->jelix = $jelix; 90 } 91 92 /** 93 * Intercept the soapServer method call in order to handle the call thrue the process method oj the coordinator 94 * @param string $soapOperationName Soap operation name (ie action name) 95 * @param array $soapArgsSoap Params for the operation 96 * @return mixed data, the soap server will transform it in a soap response 97 * Use of reflexion thrue jWSDL in order to map arg array to action params 98 */ 99 function __call($soapOperationName,$soapArgs){ 100 101 $this->jelix->request->params['action'] = $this->jelix->request->params['action'].':'.$soapOperationName; 102 103 $operationParams = $this->jelix->wsdl->getOperationParams($soapOperationName); 104 $i = 0; 105 foreach(array_keys($operationParams) as $paramName){ 106 $this->jelix->request->params[$paramName] = $soapArgs[$i]; 107 $i++; 108 } 109 110 $this->jelix->process($this->jelix->request); 111 return $this->jelix->response->data; 112 } 113 } 114 ?> -
../jelix/core/defaultconfig.ini.php
old new 45 45 css= jResponseCss 46 46 ltx2pdf= jResponseLatexToPdf 47 47 tcpdf = jResponseTcpdf 48 soap=jResponseSoap 48 49 49 50 [_coreResponses] 50 51 html = jResponseHtml … … 67 68 css= jResponseCss 68 69 ltx2pdf= jResponseLatexToPdf 69 70 tcpdf = jResponseTcpdf 71 soap=jResponseSoap 70 72 71 73 [error_handling] 72 74 messageLogFormat = "%date%\t[%code%]\t%msg%\t%file%\t%line%\n" -
../jelix/utils/jWSDL.class.php
old new 1 <?php 2 /** 3 * @package jelix 4 * @subpackage utils 5 * @author Sylvain de Vathaire 6 * @contributor 7 * @copyright 2008 Sylvain de Vathaire 8 * @link http://www.jelix.org 9 * @licence GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html 10 */ 11 12 13 require_once(LIB_PATH.'wshelper/WSDLStruct.class.php'); 14 require_once(LIB_PATH.'wshelper/WSDLException.class.php'); 15 require_once(LIB_PATH.'wshelper/WSException.class.php'); 16 require_once(LIB_PATH.'wshelper/IPXMLSchema.class.php'); 17 require_once(LIB_PATH.'wshelper/IPPhpDoc.class.php'); 18 require_once(LIB_PATH.'wshelper/IPReflectionClass.class.php'); 19 require_once(LIB_PATH.'wshelper/IPReflectionCommentParser.class.php'); 20 require_once(LIB_PATH.'wshelper/IPReflectionMethod.class.php'); 21 require_once(LIB_PATH.'wshelper/IPReflectionProperty.class.php'); 22 23 24 25 /** 26 * object to generate WSDL files and web services documentation 27 * we have 1 WSDL file for each soap web service, each service is implemented by 1 Jelix controller 28 * @package jelix 29 * @subpackage utils 30 */ 31 class jWSDL { 32 33 /** 34 * module name 35 */ 36 public $module; 37 38 /** 39 * controller name 40 */ 41 public $controller; 42 43 /** 44 * controller class name 45 */ 46 private $controllerClassName; 47 48 /** 49 * WSDL file path (cached file) 50 */ 51 public $WSDLfilePath; 52 53 54 private $_ctrlpath; 55 56 private $_dirname = 'WSDL'; 57 private $_cacheSuffix = '.wsdl'; 58 59 60 public function __construct($module, $controller){ 61 62 $this->module = $module; 63 $this->controller = $controller; 64 65 $this->_createPath(); 66 $this->_createCachePath(); 67 } 68 69 /** 70 * Détermine le chemin du controlleur 71 */ 72 private function _createPath(){ 73 global $gJConfig; 74 75 //Check module availability 76 if(!isset($gJConfig->_modulesPathList[$this->module])){ 77 throw new jExceptionSelector('jelix~errors.module.unknow', $this->module); 78 } 79 80 //Build controller path 81 $this->_ctrlpath = $gJConfig->_modulesPathList[$this->module].'controllers/'.$this->controller.'.soap.php'; 82 83 //Check controller availability 84 if(!file_exists($this->_ctrlpath)){ 85 throw new jException('jelix~errors.action.unknow',$this->controller); 86 } 87 88 //Check controller declaration 89 require_once($this->_ctrlpath); 90 $this->controllerClassName = $this->controller.'Ctrl'; 91 if(!class_exists($this->controllerClassName,false)){ 92 throw new jException('jelix~errors.ad.controller.class.unknow', array('jWSDL', $this->controllerClassName, $this->_ctrlpath)); 93 } 94 95 } 96 97 /** 98 * Build the WSDL cache file path 99 */ 100 private function _createCachePath(){ 101 $this->_cachePath = JELIX_APP_TEMP_PATH.'compiled/'.$this->_dirname.'/'.$this->module.'~'.$this->controller.$this->_cacheSuffix; 102 } 103 104 /** 105 * Return the WSDL cache file path (WSDL is updated if necessary) 106 */ 107 public function getWSDLFilePath(){ 108 $this->_updateWSDL(); 109 return $this->_cachePath; 110 } 111 112 /** 113 * Return the WSDL file content (WSDL is updated if necessary) 114 */ 115 public function getWSDLFile(){ 116 $this->_updateWSDL(); 117 return file_get_contents($this->_cachePath); 118 } 119 120 /** 121 * Return array of params object for the operation $operationName 122 * @param $operationName string Name of the operation (controller method) 123 * @return array of params object (empty if no params) 124 */ 125 public function getOperationParams($operationName){ 126 127 $IPReflectionMethod = new IPReflectionMethod($this->controllerClassName, $operationName); 128 return $IPReflectionMethod->parameters; 129 } 130 131 /** 132 * Update the WSDL cache file 133 */ 134 private function _updateWSDL(){ 135 136 global $gJConfig; 137 static $updated = FALSE; 138 139 if($updated){ 140 return; 141 } 142 143 $mustCompile = $gJConfig->compilation['force'] || !file_exists($this->_cachePath); 144 if($gJConfig->compilation['checkCacheFiletime'] && !$mustCompile){ 145 if( filemtime($this->_ctrlpath) > filemtime($this->_cachePath)){ 146 $mustCompile = true; 147 } 148 } 149 150 if($mustCompile){ 151 jFile::write($this->_cachePath, $this->_compile()); 152 } 153 $updated = TRUE; 154 } 155 156 /** 157 * Generate the WSDL content 158 */ 159 private function _compile(){ 160 161 global $gJConfig; 162 163 $serviceURL = "http://".$_SERVER['HTTP_HOST'].$gJConfig->urlengine['basePath'].'soap.php?service='.$this->module.'~'.$this->controller; 164 $serviceNameSpace = "http://".$_SERVER['HTTP_HOST'].$gJConfig->urlengine['basePath']; 165 166 $wsdl = new WSDLStruct($serviceNameSpace, $serviceURL, SOAP_RPC, SOAP_ENCODED); 167 $wsdl->setService(new IPReflectionClass($this->controllerClassName)); 168 169 try { 170 $gendoc = $wsdl->generateDocument(); 171 } catch (WSDLException $exception) { 172 throw new JException('jWSDL~errors.wsdl.generation', $exception->msg); 173 } 174 175 return $gendoc; 176 } 177 178 /** 179 * Load the class or service definition for doc purpose 180 * @param string $classname Name of the class for witch we want the doc, default doc is the service one (controller) 181 */ 182 public function doc($className=""){ 183 184 if($className != ""){ 185 if(!class_exists($className,false)){ 186 throw new jException('jelix~errors.ad.controller.class.unknow', array('WSDL generation', $className, $this->_ctrlpath)); 187 } 188 $classObject = new IPReflectionClass($className); 189 }else{ 190 $classObject = new IPReflectionClass($this->controllerClassName); 191 } 192 193 $documentation = Array(); 194 $documentation['menu'] = Array(); 195 196 if($classObject){ 197 $classObject->properties = $classObject->getProperties(false, false, false); 198 $classObject->methods = $classObject->getMethods(false, false, false); 199 foreach((array)$classObject->methods as $method) { 200 $method->params = $method->getParameters(); 201 } 202 203 $documentation['class'] = $classObject; 204 $documentation['service'] = $this->module.'~'.$this->controller; 205 } 206 return $documentation; 207 } 208 209 /** 210 * Return an array of all the soap controllers class available in the application 211 * @return array Classname of controllers 212 */ 213 public static function getSoapControllers(){ 214 215 global $gJConfig; 216 217 $modules = $gJConfig->_modulesPathList; 218 $controllers = array(); 219 220 foreach($modules as $module){ 221 if(is_dir($module.'controllers')){ 222 if ($handle = opendir($module.'controllers')) { 223 $moduleName = basename($module); 224 while (false !== ($file = readdir($handle))) { 225 if (substr($file, strlen($file) - strlen('.soap.php')) == '.soap.php') { 226 $controller = array(); 227 $controller['class'] = substr($file, 0, strlen($file) - strlen('.soap.php')); 228 $controller['module'] = $moduleName; 229 $controller['service'] = $moduleName.'~'.$controller['class']; 230 array_push($controllers, $controller); 231 } 232 } 233 closedir($handle); 234 } 235 } 236 } 237 return $controllers; 238 } 239 } 240 ?> -
../jelix-scripts/templates/www/soap.php.tpl
old new 1 <?php 2 /** 3 * @package %%$appname%% 4 * @subpackage www 5 * @author 6 * @contributor 7 * @copyright 8 */ 9 10 require_once ('%%rp_jelix%%init.php'); 11 require_once ('%%rp_app%%application.init.php'); 12 13 require_once (JELIX_LIB_CORE_PATH.'jSoapCoordinator.class.php'); 14 require_once (JELIX_LIB_CORE_PATH.'request/jSoapRequest.class.php'); 15 16 ini_set("soap.wsdl_cache_enabled", "0"); // disabling PHP's WSDL cache 17 18 $config_file = 'index/config.ini.php'; 19 $jelix = new JSoapCoordinator($config_file); 20 $jelix->request = new JSoapRequest(); 21 $jelix->request->initService(); 22 $jelix->processSoap(); 23 ?>
