Ticket #377: soapSupport.diff

File soapSupport.diff, 16.6 kB (added by sylvain261, 9 months ago)

Patch avec uniquement les éléments nécessaires au support SOAP (donc sans le module jWSDL)

  • ../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*/ 
     17class 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*/ 
     18final 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 */ 
     15require_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 */ 
     25class 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*/ 
     80class 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  
    4545css= jResponseCss 
    4646ltx2pdf= jResponseLatexToPdf 
    4747tcpdf = jResponseTcpdf 
     48soap=jResponseSoap 
    4849 
    4950[_coreResponses] 
    5051html = jResponseHtml 
     
    6768css= jResponseCss 
    6869ltx2pdf= jResponseLatexToPdf 
    6970tcpdf = jResponseTcpdf 
     71soap=jResponseSoap 
    7072 
    7173[error_handling] 
    7274messageLogFormat = "%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 
     13require_once(LIB_PATH.'wshelper/WSDLStruct.class.php'); 
     14require_once(LIB_PATH.'wshelper/WSDLException.class.php'); 
     15require_once(LIB_PATH.'wshelper/WSException.class.php'); 
     16require_once(LIB_PATH.'wshelper/IPXMLSchema.class.php'); 
     17require_once(LIB_PATH.'wshelper/IPPhpDoc.class.php'); 
     18require_once(LIB_PATH.'wshelper/IPReflectionClass.class.php'); 
     19require_once(LIB_PATH.'wshelper/IPReflectionCommentParser.class.php'); 
     20require_once(LIB_PATH.'wshelper/IPReflectionMethod.class.php'); 
     21require_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 */ 
     31class 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 
     10require_once ('%%rp_jelix%%init.php'); 
     11require_once ('%%rp_app%%application.init.php'); 
     12 
     13require_once (JELIX_LIB_CORE_PATH.'jSoapCoordinator.class.php'); 
     14require_once (JELIX_LIB_CORE_PATH.'request/jSoapRequest.class.php'); 
     15 
     16ini_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?> 
Download in other formats: Original Format