MIOLO20
Carregando...
Procurando...
Nenhuma entrada encontrada
class.phpwsdl.php
Ir para a documentação deste ficheiro.
1<?php
2
3/*
4PhpWsdl - Generate WSDL from PHP
5Copyright (C) 2011 Andreas Zimmermann, wan24.de
6
7This program is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free Software
9Foundation; either version 3 of the License, or (at your option) any later
10version.
11
12This program is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License along with
17this program; if not, see <http://www.gnu.org/licenses/>.
18*/
19
20if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
21 exit;
22
23// Debugging
24/*PhpWsdl::$Debugging=true;// Enable debugging
25PhpWsdl::$DebugFile='./cache/debug.log';// The logfile to write the debugging messages to
26PhpWsdl::$DebugBackTrace=false;// Include backtrace information in debugging messages?*/
27
28// Initialize PhpWsdl
29PhpWsdl::Init();
30
31// You don't require class.phpwsdlelement.php and class.phpwsdlcomplex.php,
32// as long as you don't use complex types. So you may comment those two
33// requires out.
34// You may also disable loading the class.phpwsdlproxy.php, if you don't plan
35// to use the proxy class for your webservice.
36require_once(dirname(__FILE__).'/class.phpwsdlformatter.php');
37require_once(dirname(__FILE__).'/class.phpwsdlobject.php');
38require_once(dirname(__FILE__).'/class.phpwsdlparser.php');
39require_once(dirname(__FILE__).'/class.phpwsdlproxy.php');
40require_once(dirname(__FILE__).'/class.phpwsdlparam.php');
41require_once(dirname(__FILE__).'/class.phpwsdlmethod.php');
42require_once(dirname(__FILE__).'/class.phpwsdlelement.php');
43require_once(dirname(__FILE__).'/class.phpwsdlcomplex.php');
44
45// Classe sobrescrita do SoapServer para gerar log das chamadas webservices
46require_once(dirname(__FILE__).'/../webServicesServer.class');
47
48// Do things after the environment is configured
49PhpWsdl::PostInit();
50
58class PhpWsdl{
64 public static $VERSION='2.3';
70 public static $AutoRun=false;
76 public static $Config=Array();
82 public static $ProxyObject=null;
88 public static $ProxyServer=null;
94 public static $UseProxyWsdl=false;
100 public $Name;
106 public $Docs=null;
112 public $NameSpace=null;
118 public $EndPoint=null;
124 public $WsdlUri=null;
130 public $PhpUri=null;
136 public $DocUri=null;
149 public $Files=Array();
155 public $Types=null;
161 public $Methods=null;
168 public $Optimize=true;
174 public $WSDL=null;
180 public $HTML=null;
186 public $PHP=null;
193 public static $BasicTypes=Array(
194 'anyType',
195 'anyURI',
196 'base64Binary',
197 'boolean',
198 'byte',
199 'date',
200 'decimal',
201 'double',
202 'duration',
203 'dateTime',
204 'float',
205 'gDay',
206 'gMonthDay',
207 'gYearMonth',
208 'gYear',
209 'hexBinary',
210 'int',
211 'integer',
212 'long',
213 'NOTATION',
214 'number',
215 'QName',
216 'short',
217 'string',
218 'time'
219 );
225 public static $NonNillable=Array(
226 'boolean',
227 'decimal',
228 'double',
229 'float',
230 'int',
231 'integer',
232 'long',
233 'number',
234 'short'
235 );
241 public static $CacheFolder=null;
247 public static $CacheFolderWriteAble=null;
256 public static $CacheTime=3600;
262 public static $CacheAllWsdl=false;
268 public $ParseDocs=true;
274 public $IncludeDocs=true;
280 public $ForceOutputWsdl=false;
292 public $ForceOutputHtml=false;
304 public $HtmlHeadLine=null;
310 public $ForceOutputPhp=false;
316 public $ForceNotOutputPhp=false;
322 public static $classRx='/^.*class\s+([^\s]+)\s*\{.*$/is';
328 public static $HTML2PDFLicenseKey=null;
334 public static $HTML2PDFAPI='http://online.htmltopdf.de/';
340 public static $HTML2PDFSettings=Array();
346 public $SourcesParsed=false;
358 public $SoapServer=null;
364 public $RequireLogin=false;
370 public static $DebugInfo=Array();
376 public static $Debugging=false;
382 public static $DebugFile=null;
388 public static $DebugBackTrace=false;
394 public static $NameSpaces=null;
395
411 public function PhpWsdl(
412 $nameSpace=null,
413 $endPoint=null,
414 $cacheFolder=null,
415 $file=null,
416 $name=null,
417 $methods=null,
418 $types=null,
419 $outputOnRequest=false,
420 $runServer=false
421 ){
423 $nameSpace,
424 $endPoint,
425 $cacheFolder,
426 $file,
427 $name,
428 $methods,
429 $types,
430 $outputOnRequest,
431 $runServer
432 );
433 }
434
435 public function __construct(
436 $nameSpace=null,
437 $endPoint=null,
438 $cacheFolder=null,
439 $file=null,
440 $name=null,
441 $methods=null,
442 $types=null,
443 $outputOnRequest=false,
444 $runServer=false
445 ){
446 // Quick mode
447 self::Debug('PhpWsdl constructor called');
448 $quickRun=false;
449 if($nameSpace===true){
450 self::Debug('Quick mode detected');
451 $quickRun=true;
452 $nameSpace=null;
453 if(!is_null($endPoint)){
454 if(self::$Debugging)
455 self::Debug('Filename(s): '.print_r($endPoint,true));
456 $endPoint=null;
457 }
458 }
459 // SOAP server options
460 $this->SoapServerOptions=Array(
461 'soap_version' => SOAP_1_2,
462 'encoding' => 'UTF-8',
463 'compression' => SOAP_COMPRESSION_ACCEPT|SOAP_COMPRESSION_GZIP|9
464 );
465 // Optimizer settings
466 $this->Optimize=!isset($_GET['readable']);// Call with "?WSDL&readable" to get human readable WSDL
467 self::Debug('Optimizer is '.(($this->Optimize)?'enabled':'disabled'));
468 // Cache settings
469 if(!is_null($cacheFolder)){
470 self::Debug('Cache folder is '.$cacheFolder);
471 self::$CacheFolder=$cacheFolder;
472 }
473 // Namespace
474 $this->NameSpace=(is_null($nameSpace))?$this->DetermineNameSpace():$nameSpace;
475 self::Debug('Namespace is '.$this->NameSpace);
476 // Endpoint
477 $this->EndPoint=((!is_null($endPoint)))?$endPoint:$this->DetermineEndPoint();
478 self::Debug('Endpoint is '.$this->EndPoint);
479 // Name
480 if(!is_null($name)){
481 self::Debug('Name is '.$name);
482 $this->Name=$name;
483 }
484 // Source files
485 if(!is_null($file)){
486 if(self::$Debugging)
487 self::Debug('Filename(s): '.print_r($file,true));
488 $this->Files=array_merge($this->Files,(is_array($file))?$file:Array($file));
489 }
490 // Methods
491 $this->Methods=(!is_null($methods))?$methods:Array();
492 if(sizeof($this->Methods)>0&&self::$Debugging)
493 self::Debug('Methods: '.print_r($this->Methods,true));
494 // Types
495 $this->Types=(!is_null($types))?$types:Array();
496 if(sizeof($this->Types)>0&&self::$Debugging)
497 self::Debug('Types: '.print_r($this->Types,true));
498 // Constructor hook
500 'ConstructorHook',
501 Array(
502 'server' => $this,
503 'output' => &$outputOnRequest,
504 'run' => &$runServer,
505 'quickmode' => &$quickRun
506 )
507 );
508 // WSDL output
509 if($outputOnRequest&&!$runServer)
510 $this->OutputWsdlOnRequest();
511 // Run the server
512 if($quickRun||$runServer)
513 $this->RunServer(null,(is_bool($runServer))?null:$runServer);
514 }
515
532 public static function CreateInstance(
533 $nameSpace=null,
534 $endPoint=null,
535 $cacheFolder=null,
536 $file=null,
537 $name=null,
538 $methods=null,
539 $types=null,
540 $outputOnRequest=false,
541 $runServer=false
542 ){
543 self::Debug('Create new PhpWsdl instance');
544 $obj=null;
546 'BeforeCreateInstanceHook',
547 Array(
548 'server' => &$obj,
549 'namespace' => &$nameSpace,
550 'endpoint' => &$endPoint,
551 'cachefolder' => &$cacheFolder,
552 'file' => &$file,
553 'name' => &$name,
554 'methods' => &$methods,
555 'types' => &$types,
556 'outputonrequest'=> &$outputOnRequest,
557 'runserver' => &$runServer
558 )
559 );
560 if(is_null($obj))
561 $obj=new PhpWsdl($nameSpace,$endPoint,$cacheFolder,$file,$name,$methods,$types,$outputOnRequest,$runServer);
563 'CreateInstanceHook',
564 Array(
565 'server' => &$obj
566 )
567 );
568 return $obj;
569 }
570
576 public static function RunQuickMode($file=null){
577 self::Debug('Run quick mode');
578 $server=self::CreateInstance();
579 if(!is_null($file))
580 $server->Files=(is_array($file))?$file:Array($file);
581 $server->RunServer();
582 }
583
589 public function IsWsdlRequested(){
590 return $this->ForceOutputWsdl||((isset($_GET['wsdl'])||isset($_GET['WSDL']))&&!$this->ForceNotOutputWsdl);
591 }
592
598 public function IsHtmlRequested(){
599 return $this->ForceOutputHtml||(strlen(file_get_contents('php://input'))<1&&!$this->ForceNotOutputHtml);
600 }
601
607 public function IsPhpRequested(){
608 return $this->ForceOutputPhp||((isset($_GET['phpsoapclient'])||isset($_GET['PHPSOAPCLIENT']))&&!$this->ForceNotOutputPhp);
609 }
610
616 public function IsSoapRequest(){
617 return !$this->IsHtmlRequested()&&!$this->IsWsdlRequested()&&!$this->IsPhpRequested();
618 }
619
625 public function IsOnlyGlobal(){
626 $res=true;
627 $i=-1;
628 $len=sizeof($this->Methods);
629 while(++$i<$len)
630 if(!$this->Methods[$i]->IsGlobal){
631 $res=false;
632 break;
633 }
634 return $res;
635 }
636
642 public static function DisableCache($allCaching=true){
643 self::Debug('Disable '.(($allCaching)?'all':'this').' caching');
644 if($allCaching)
645 self::$CacheFolder=null;
646 if(!$allCaching)
647 self::$CacheTime=0;
648 }
649
656 public static function EnableCache($folder=null,$timeout=null){
657 if(is_null($folder)){
658 if(self::IsCacheFolderWriteAble('./cache')){
659 $folder='./cache';
660 }else if(self::IsCacheFolderWriteAble(dirname(__FILE__).'/cache')){
661 $folder=dirname(__FILE__).'/cache';
662 }else if(self::IsCacheFolderWriteAble(sys_get_temp_dir())){
663 $folder=sys_get_temp_dir();
664 }else{
665 self::Debug('Could not find a cache folder');
666 }
667 }
668 if(is_null($timeout))
669 $timeout=(self::$CacheTime!=0)?self::$CacheTime:3600;
670 self::Debug('Enable cache in folder "'.((is_null($folder))?'(none)':$folder).'" with timeout '.$timeout.' seconds');
671 self::$CacheFolder=$folder;
672 self::$CacheTime=$timeout;
673 }
674
680 public function DetermineConfiguration(){
681 if(!is_null($this->GetWsdlFromCache()))
682 return true;
683 $this->ParseSource();
684 $mLen=sizeof($this->Methods);
685 $tLen=sizeof($this->Types);
686 $fLen=sizeof($this->Files);
687 if($this->ConfigurationDetermined)
688 return ($mLen>0||$tLen>0)&&!is_null($this->Name);
689 self::Debug('Determine configuration');
690 $this->ConfigurationDetermined=true;
691 $tryWebService=
692 !$this->IsFileInList('class.webservice.php')&&
693 (
694 file_exists('class.webservice.php')||
695 file_exists(dirname(__FILE__).'/class.webservice.php')
696 );
697 // No methods or types? Try to parse them from the current script
698 if($mLen<1&&$tLen<1){
699 $tryFiles=Array();
700 if($tryWebService){
701 if(file_exists('class.webservice.php'))
702 $tryFiles[]='class.webservice.php';
703 if(file_exists(dirname(__FILE__).'/class.webservice.php'))
704 $tryFiles[]=dirname(__FILE__).'/class.webservice.php';
705 }
706 if(!$this->IsFileInList($_SERVER['SCRIPT_FILENAME']))
707 $tryFiles[]=$_SERVER['SCRIPT_FILENAME'];
708 $i=-1;
709 $len=sizeof($tryFiles);
710 while(++$i<$len){
711 $file=$tryFiles[$i];
712 self::Debug('Try to load objects from '.$file);
713 $this->ParseSource(false,file_get_contents($file));
714 $mLen=sizeof($this->Methods);
715 $tLen=sizeof($this->Types);
716 if($mLen<1&&$tLen<1)
717 continue;
718 self::Debug('Found objects, adding the file to list');
719 $this->Files[]=$file;
720 $fLen++;
721 break;
722 }
723 if($mLen<1&&$tLen<1)
724 return false;
725 }
726 // No class name? Try to parse one from the current files
727 if(!is_null($this->Name))
728 return true;
729 $tryFiles=Array();
730 if(!$this->IsFileInList($_SERVER['SCRIPT_FILENAME']))
731 $tryFiles[]=$_SERVER['SCRIPT_FILENAME'];
732 if($tryWebService){
733 if(file_exists('class.webservice.php'))
734 $tryFiles[]='class.webservice.php';
735 if(file_exists(dirname(__FILE__).'/class.webservice.php'))
736 $tryFiles[]=dirname(__FILE__).'/class.webservice.php';
737 }
738 $tryFiles=array_merge($this->Files,$tryFiles);
739 $i=-1;
740 $len=sizeof($tryFiles);
741 while(++$i<$len){
742 $file=$tryFiles[$i];
743 self::Debug('Try to determine the class name from '.$file);
744 $temp=file_get_contents($file);
745 if(!preg_match(self::$classRx,$temp))
746 continue;
747 $class=preg_replace(self::$classRx,"$1",$temp);
748 self::Debug('Found class name '.$class);
749 break;
750 }
751 // No class name yet? Use the default if only global methods are present
752 if(is_null($class)&&$this->IsOnlyGlobal()){
753 self::Debug('Using default webservice name');
754 $class='SoapWebService';
755 }
756 $this->Name=$class;
757 return !is_null($class);
758 }
759
763 public function DetermineEndPoint(){
764 return ((isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']=='on')?'https':'http').'://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'];
765 }
766
770 public function DetermineNameSpace()
771 {
772 $protocolo = 'http';
773 if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' )
774 {
775 $protocolo = 'https';
776 }
777 return $protocolo . '://'.$_SERVER['SERVER_NAME'].str_replace(basename($_SERVER['SCRIPT_NAME']),'',$_SERVER['SCRIPT_NAME']);
778 }
779
786 public function IsFileInList($file){
787 $file=preg_quote(basename($file));
788 $i=-1;
789 $fLen=sizeof($this->Files);
790 while(++$i<$fLen)
791 if(preg_match('/^(.*\/)?'.$file.'$/i',$this->Files[$i]))
792 return true;
793 return false;
794 }
795
803 public function CreateWsdl($reCreate=false,$optimizer=false){
804 self::Debug('Create WSDL');
805 // Ask the cache
806 if(!$reCreate&&(self::$CacheAllWsdl||!$this->IncludeDocs||$optimizer||$this->Optimize)){
807 self::Debug('Try to get WSDL from the cache');
808 $wsdl=$this->GetWsdlFromCache();
809 if(!is_null($wsdl)){
810 self::Debug('Using cached WSDL');
811 return (!$optimizer&&!$this->Optimize)?self::FormatXml($wsdl):$wsdl;
812 }
813 }
814 // Prepare the WSDL generator
815 if(!$this->DetermineConfiguration()){
816 $mLen=sizeof($this->Methods);
817 $tLen=sizeof($this->Types);
818 if($mLen<1&&$tLen<1){
819 self::Debug('No methods and types');
820 throw(new Exception('No methods and no complex types are available'));
821 }
822 if(is_null($this->Name)){
823 self::Debug('No name');
824 throw(new Exception('Could not determine webservice handler class name'));
825 }
826 }
827 $res=Array();
828 // Create the XML Header
830 'CreateWsdlHeaderHook',
831 Array(
832 'server' => $this,
833 'res' => &$res,
834 'optimizer' => &$optimizer
835 )
836 );
837 // Create types
839 'CreateWsdlTypeSchemaHook',
840 Array(
841 'server' => $this,
842 'res' => &$res,
843 'optimizer' => &$optimizer
844 )
845 );
846 // Create messages
848 'CreateWsdlMessagesHook',
849 Array(
850 'server' => $this,
851 'res' => &$res,
852 'optimizer' => &$optimizer
853 )
854 );
855 // Create port types
857 'CreateWsdlPortsHook',
858 Array(
859 'server' => $this,
860 'res' => &$res,
861 'optimizer' => &$optimizer
862 )
863 );
864 // Create bindings
866 'CreateWsdlBindingsHook',
867 Array(
868 'server' => $this,
869 'res' => &$res,
870 'optimizer' => &$optimizer
871 )
872 );
873 // Create the service
875 'CreateWsdlServiceHook',
876 Array(
877 'server' => $this,
878 'res' => &$res,
879 'optimizer' => &$optimizer
880 )
881 );
882 // Finish the WSDL XML string
884 'CreateWsdlFooterHook',
885 Array(
886 'server' => $this,
887 'res' => &$res,
888 'optimizer' => &$optimizer
889 )
890 );
891 // Run the optimizer
893 'CreateWsdlOptimizeHook',
894 Array(
895 'server' => $this,
896 'res' => &$res,
897 'optimizer' => &$optimizer
898 )
899 );
900 // Fill the cache
901 if(self::$CacheAllWsdl||!$this->IncludeDocs||$optimizer||$this->Optimize){
902 self::Debug('Cache created WSDL');
903 $this->WriteWsdlToCache(
904 (
905 !self::$CacheAllWsdl&&
906 !$optimizer&&
907 !$this->Optimize
908 )
909 ?self::OptimizeXml($res)
910 :$res
911 ,
912 null,
913 null,
914 true
915 );
916 }
917 return $this->WSDL;
918 }
919
926 public static function CreateWsdlHeader($data){
927 self::Debug('CreateWsdlHeader');
928 $res=&$data['res'];
929 $server=$data['server'];
930 $res[]='<?xml version="1.0" encoding="UTF-8"?>';
931 $temp=Array();
932 $keys=array_keys(self::$NameSpaces);
933 $i=-1;
934 $len=sizeof($keys);
935 while(++$i<$len)
936 $temp[]='xmlns:'.$keys[$i].'="'.self::$NameSpaces[$keys[$i]].'"';
937 $res[]='<wsdl:definitions xmlns:tns="'.$server->NameSpace.'" targetNamespace="'.$server->NameSpace.'" '.implode(' ',$temp).'>';
938 return true;
939 }
940
947 public static function CreateWsdlTypeSchema($data){
948 self::Debug('CreateWsdlTypeSchema');
949 $res=&$data['res'];
950 $server=$data['server'];
951 $tLen=sizeof($server->Types);
952 if($tLen>0){
953 $res[]='<wsdl:types>';
954 $res[]='<s:schema targetNamespace="'.$server->NameSpace.'">';
955 $i=-1;
956 while(++$i<$tLen)
957 $res[]=$server->Types[$i]->CreateType($server);
959 'CreateWsdlTypesHook',
960 $data
961 );
962 $res[]='</s:schema>';
963 $res[]='</wsdl:types>';
964 }
965 return true;
966 }
967
974 public static function CreateWsdlMessages($data){
975 self::Debug('CreateWsdlMessages');
976 $res=&$data['res'];
977 $server=$data['server'];
978 $i=-1;
979 $mLen=sizeof($server->Methods);
980 while(++$i<$mLen)
981 $res[]=$server->Methods[$i]->CreateMessages($server);
982 return true;
983 }
984
991 public static function CreateWsdlPorts($data){
992 self::Debug('CreateWsdlPorts');
993 $res=&$data['res'];
994 $server=$data['server'];
995 $res[]='<wsdl:portType name="'.$server->Name.'Soap">';
996 $i=-1;
997 $mLen=sizeof($server->Methods);
998 while(++$i<$mLen)
999 $res[]=$server->Methods[$i]->CreatePortType($server);
1001 'CreateWsdlPortsAddHook',
1002 $data
1003 );
1004 $res[]='</wsdl:portType>';
1005 return true;
1006 }
1007
1014 public static function CreateWsdlBindings($data){
1015 self::Debug('CreateWsdlBindings');
1016 $res=&$data['res'];
1017 $server=$data['server'];
1018 $res[]='<wsdl:binding name="'.$server->Name.'Soap" type="tns:'.$server->Name.'Soap">';
1019 $res[]='<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />';
1020 $i=-1;
1021 $mLen=sizeof($server->Methods);
1022 while(++$i<$mLen)
1023 $res[]=$server->Methods[$i]->CreateBinding($server);
1025 'CreateWsdlBindingsAddHook',
1026 $data
1027 );
1028 $res[]='</wsdl:binding>';
1029 return true;
1030 }
1031
1038 public static function CreateWsdlService($data){
1039 self::Debug('CreateWsdlService');
1040 $res=&$data['res'];
1041 $server=$data['server'];
1042 $res[]='<wsdl:service name="'.$server->Name.'">';
1043 if($server->IncludeDocs&&!$server->Optimize&&!is_null($server->Docs))
1044 $res[]='<wsdl:documentation><![CDATA['.$server->Docs.']]></wsdl:documentation>';
1045 $res[]='<wsdl:port name="'.$server->Name.'Soap" binding="tns:'.$server->Name.'Soap">';
1046 $res[]='<soap:address location="'.$server->EndPoint.'" />';
1047 $res[]='</wsdl:port>';
1049 'CreateWsdlServiceAddHook',
1050 $data
1051 );
1052 $res[]='</wsdl:service>';
1053 return true;
1054 }
1055
1062 public static function CreateWsdlFooter($data){
1063 self::Debug('CreateWsdlFooter');
1064 $res=&$data['res'];
1065 $res[]='</wsdl:definitions>';
1066 return true;
1067 }
1068
1075 public static function CreateWsdlOptimize($data){
1076 self::Debug('CreateWsdlOptimize');
1077 $res=&$data['res'];
1078 $server=$data['server'];
1079 $optimizer=&$data['optimizer'];
1080 $res=implode('',$res);
1081 $res=(!$optimizer&&!$server->Optimize)
1082 ?self::FormatXml($res)
1083 :self::OptimizeXml($res);
1084 $server->WSDL=$res;
1085 return true;
1086 }
1087
1094 public static function OptimizeXml($xml){
1095 self::Debug('Optimize XML');
1096 return preg_replace('/[\n|\t]/','',$xml);
1097 }
1098
1105 public static function FormatXml($xml){
1106 self::Debug('Produce human readable XML');
1107 $input=fopen('data://text/plain,'.$xml,'r');
1108 $output=fopen('php://temp','w');
1109 $xf=new PhpWsdlFormatter($input,$output);
1110 $xf->format();
1111 rewind($output);
1112 $xml=stream_get_contents($output);
1113 fclose($input);
1114 fclose($output);
1115 return $xml;
1116 }
1117
1124 public static function InterpretService($data){
1125 self::Debug('Interpret service');
1126 $server=$data['server'];
1127 $info=explode(' ',$data['keyword'][1],2);
1128 if(sizeof($info)<1){
1129 self::Debug('WARNING: Invalid service definition');
1130 return true;
1131 }
1132 $server->Name=$info[0];
1133 if($server->ParseDocs&&sizeof($info)>1&&is_null($server->Docs))
1134 $server->Docs=$info[1];
1135 return true;
1136 }
1137
1144 public function ParseSource($init=false,$str=null){
1145 self::Debug('Parse the source');
1146 if($init){
1147 self::Debug('Init methods and types');
1148 $this->Methods=Array();
1149 $this->Types=Array();
1150 $this->SourcesParsed=false;
1151 }
1152 if(is_null($str)){
1153 if($this->SourcesParsed)
1154 return;
1155 self::Debug('Load source files');
1156 $this->SourcesParsed=true;
1157 $fLen=sizeof($this->Files);
1158 if($fLen<1)
1159 return;
1160 // Load the source
1161 $src=Array();
1162 $i=-1;
1163 while(++$i<$fLen)
1164 $src[]=trim(file_get_contents($this->Files[$i]));
1165 }else{
1166 self::Debug('Use given string');
1167 $src=Array($str);
1168 }
1169 // Parse the source
1170 self::Debug('Run the parser');
1171 $parser=new PhpWsdlParser($this);
1172 $parser->Parse(implode("\n",$src));
1173 }
1174
1180 public function OutputWsdl($withHeaders=true){
1181 if(!self::CallHook(
1182 'OutputWsdlHook',
1183 Array(
1184 'server' => $this
1185 )
1186 )
1187 )
1188 return;
1189 self::Debug('Output WSDL');
1190 if($withHeaders)
1191 header('Content-Type: text/xml; charset=UTF-8',true);
1192 echo $this->CreateWsdl();
1193 }
1194
1201 public function OutputWsdlOnRequest($andExit=true){
1202 if(!$this->IsWsdlRequested())
1203 return false;
1204 $this->OutputWsdl();
1205 if($andExit){
1206 self::Debug('Exit script execution');
1207 exit;
1208 }
1209 return true;
1210 }
1211
1220 public function OutputHtml($withHeaders=true,$echo=true,$cache=true){
1221 self::Debug('Output HTML');
1222 if(sizeof($this->Methods)<1)
1223 $this->CreateWsdl();
1224 if(!self::CallHook(
1225 'OutputHtmlHook',
1226 Array(
1227 'server' => $this
1228 )
1229 )
1230 )
1231 return;
1232 // Header
1233 if($withHeaders)
1234 header('Content-Type: text/html; charset=UTF-8',true);
1235 $this->GetWsdlFromCache();
1236 if(!is_null($this->HTML)){
1237 if($echo)
1238 echo $this->HTML;
1239 return $this->HTML;
1240 }
1241 $res=Array();
1242 $res[]='<html>';
1243 $res[]='<head>';
1244 $res[]='<title>'.((is_null($this->HtmlHeadLine))?$this->Name.' interface description':nl2br(htmlentities($this->HtmlHeadLine))).'</title>';
1245 $res[]='<style type="text/css" media="all">';
1246 $res[]='body{font-family:Calibri,Arial;background-color:#fefefe;}';
1247 $res[]='.pre{font-family:Courier;}';
1248 $res[]='.normal{font-family:Calibri,Arial;}';
1249 $res[]='.bold{font-weight:bold;}';
1250 $res[]='h1,h2,h3{font-family:Verdana,Times;}';
1251 $res[]='h1{border-bottom:1px solid gray;}';
1252 $res[]='h2{border-bottom:1px solid silver;}';
1253 $res[]='h3{border-bottom:1px dashed silver;}';
1254 $res[]='a{text-decoration:none;}';
1255 $res[]='a:hover{text-decoration:underline;}';
1256 $res[]='.blue{color:#3400FF;}';
1257 $res[]='.lightBlue{color:#5491AF;}';
1258 if(!is_null(self::$HTML2PDFLicenseKey)&&self::$HTML2PDFSettings['attachments']=='1')
1259 $res[]='.print{display:none;}';
1261 'CreateHtmlCssHook',
1262 Array(
1263 'server' => $this,
1264 'res' => &$res
1265 )
1266 );
1267 $res[]='</style>';
1268 $res[]='<style type="text/css" media="print">';
1269 $res[]='.noprint{display:none;}';
1270 if(!is_null(self::$HTML2PDFLicenseKey)&&self::$HTML2PDFSettings['attachments']=='1')
1271 $res[]='.print{display:block;}';
1273 'CreateHtmlCssPrintHook',
1274 Array(
1275 'server' => $this,
1276 'res' => &$res
1277 )
1278 );
1279 $res[]='</style>';
1280 $res[]='</head>';
1281 $res[]='<body>';
1282 $types=$this->SortObjectsByName($this->Types);
1283 $methods=$this->SortObjectsByName($this->Methods);
1284 // General information
1286 'CreateHtmlGeneralHook',
1287 Array(
1288 'server' => $this,
1289 'res' => &$res,
1290 'methods' => &$methods,
1291 'types' => &$types
1292 )
1293 );
1294 // Index
1296 'CreateHtmlIndexHook',
1297 Array(
1298 'server' => $this,
1299 'res' => &$res,
1300 'methods' => &$methods,
1301 'types' => &$types
1302 )
1303 );
1304 // Complex types
1306 'CreateHtmlComplexTypesHook',
1307 Array(
1308 'server' => $this,
1309 'res' => &$res,
1310 'methods' => &$methods,
1311 'types' => &$types
1312 )
1313 );
1314 // Methods
1316 'CreateHtmlMethodsHook',
1317 Array(
1318 'server' => $this,
1319 'res' => &$res,
1320 'methods' => &$methods,
1321 'types' => &$types
1322 )
1323 );
1324 // HTML2PDF link
1325 $param=Array(
1326 'plain' => '1',
1327 'filename' => $this->Name.'-webservices.pdf',
1328 'print' => '1'
1329 );
1330 if(!is_null(self::$HTML2PDFLicenseKey)){
1331 // Use advanced HTML2PDF API
1332 $temp=array_merge(self::$HTML2PDFSettings,Array(
1333 'url' => $this->GetDocUri()
1334 ));
1335 if($temp['attachments']=='1'){
1336 $temp['attachment_1']=$this->Name.'.wsdl:'.$this->GetWsdlUri();
1337 $cnt=1;
1338 if($this->ParseDocs&&$this->IncludeDocs){
1339 $cnt=2;
1340 $temp['attachment_2']=$this->Name.'-doc.wsdl:'.$this->GetWsdlUri().'&readable';
1341 }
1342 $cnt++;
1343 $temp['attachment_'.$cnt]=$this->Name.'.soapclient.php:'.$this->GetPhpUri();
1345 'PdfAttachmentHook',
1346 Array(
1347 'server' => $this,
1348 'cnt' => &$cnt,
1349 'param' => &$temp,
1350 'res' => &$res,
1351 'methods' => &$methods,
1352 'types' => &$types
1353 )
1354 );
1355 }
1356 $options=Array();
1357 $keys=array_keys($temp);
1358 $i=-1;
1359 $len=sizeof($keys);
1360 while(++$i<$len)
1361 $options[]=$keys[$i].'='.$temp[$keys[$i]];
1362 $options='$'.base64_encode(implode("\n",$options));
1363 $license=sha1(self::$HTML2PDFLicenseKey.self::$HTML2PDFLicenseKey).'-'.sha1($options.self::$HTML2PDFLicenseKey);
1364 $param['url']=$options;
1365 $param['license']=$license;
1366 }
1367 $temp=$param;
1368 $param=Array();
1369 $keys=array_keys($temp);
1370 $i=-1;
1371 $len=sizeof($keys);
1372 while(++$i<$len)
1373 $param[]=urlencode($keys[$i]).'='.urlencode($temp[$keys[$i]]);
1374 $pdfLink=self::$HTML2PDFAPI.'?'.implode('&',$param);
1375 // Footer
1376 $res[]='<hr>';
1377 $res[]='<p><small>Powered by <a href="http://code.google.com/p/php-wsdl-creator/">PhpWsdl</a><span class="noprint"> - PDF download: <a href="'.$pdfLink.'">Download this page as PDF</a></span></small></p>';
1378 $res[]='</body>';
1379 $res[]='</html>';
1380 // Clean up the generated HTML and send it
1381 $res=implode("\n",$res);
1382 $res=str_replace('<br />','<br>',$res);// Because nl2br will produce XHTML (and nothing if the second parameter is FALSE!?)
1383 if(!self::CallHook(
1384 'SendHtmlHook',
1385 Array(
1386 'server' => $this,
1387 'res' => &$res
1388 )
1389 )
1390 )
1391 return;
1392 $res=$res;
1393 $this->HTML=$res;
1394 if($cache)
1395 $this->WriteWsdlToCache(null,null,null,true);
1396 if($echo)
1397 echo $res;
1398 return $res;
1399 }
1400
1407 public static function CreateHtmlGeneral($data){
1408 self::Debug('CreateHtmlGeneral');
1409 $res=&$data['res'];
1410 $server=$data['server'];
1411 $res[]='<h1>'.$server->Name.' SOAP WebService interface description</h1>';
1412 $res[]='<p>Endpoint URI: <span class="pre">'.$server->EndPoint.'</span></p>';
1413 $res[]='<p>WSDL URI: <span class="pre"><a href="'.$server->GetWsdlUri().'&readable">'.$server->GetWsdlUri().'</a></span></p>';
1414 $res[]='<p>PHP SOAP client download URI: <span class="pre"><a href="'.$server->GetPhpUri().'">'.$server->GetPhpUri().'</a></span></p>';
1415 if(self::$HTML2PDFSettings['attachments']=='1'&&!is_null(self::$HTML2PDFLicenseKey))
1416 $res[]='<p class="print">The WSDL files and client proxy class(es) are attached to this PDF documentation.</p>';
1417 if(!is_null($server->Docs))
1418 $res[]='<p>'.nl2br(htmlentities($server->Docs)).'</p>';
1419 return true;
1420 }
1421
1428 public static function CreateHtmlIndex($data){
1429 self::Debug('CreateHtmlIndex');
1430 $res=&$data['res'];
1431 $types=&$data['types'];
1432 $methods=&$data['methods'];
1433 $tLen=sizeof($types);
1434 $mLen=sizeof($methods);
1435 $res[]='<div class="noprint">';
1436 $res[]='<h2>Index</h2>';
1437 if($tLen>0){
1438 $res[]='<p>Complex types:</p>';
1439 $i=-1;
1440 $res[]='<ul>';
1441 while(++$i<$tLen)
1442 $res[]='<li><a href="#'.$types[$i]->Name.'"><span class="pre">'.$types[$i]->Name.'</span></a></li>';
1443 $res[]='</ul>';
1444 }
1445 if($mLen>0){
1446 $res[]='<p>Public methods:</p>';
1447 $i=-1;
1448 $res[]='<ul>';
1449 while(++$i<$mLen)
1450 $res[]='<li><a href="#'.$methods[$i]->Name.'"><span class="pre">'.$methods[$i]->Name.'</span></a></li>';
1451 $res[]='</ul>';
1452 }
1453 $res[]='</div>';
1454 return true;
1455 }
1456
1463 public static function CreateHtmlMethods($data){
1464 self::Debug('CreateHtmlMethods');
1465 $res=&$data['res'];
1466 $methods=&$data['methods'];
1467 $mLen=sizeof($methods);
1468 if($mLen>0){
1469 $res[]='<h2>Public methods</h2>';
1470 $i=-1;
1471 while(++$i<$mLen)
1472 $methods[$i]->CreateMethodHtml(array_merge(
1473 $data,
1474 Array(
1475 'method' => $methods[$i]
1476 )
1477 ));
1478 }
1479 return true;
1480 }
1481
1488 public static function CreateHtmlComplexTypes($data){
1489 self::Debug('CreateHtmlComplexTypes');
1490 $res=&$data['res'];
1491 $types=&$data['types'];
1492 $server=$data['server'];
1493 $tLen=sizeof($server->Types);
1494 if($tLen>0){
1495 $res[]='<h2>Complex types</h2>';
1496 $i=-1;
1497 while(++$i<$tLen)
1498 $types[$i]->CreateTypeHtml(array_merge(
1499 $data,
1500 Array(
1501 'type' => $types[$i]
1502 )
1503 ));
1504 }
1505 return true;
1506 }
1507
1514 public function SortObjectsByName($obj){
1515 self::Debug('Sort objects by name');
1516 $temp=Array();
1517 $i=-1;
1518 $len=sizeof($obj);
1519 while(++$i<$len)
1520 $temp[$obj[$i]->Name]=$obj[$i];
1521 $keys=array_keys($temp);
1522 sort($keys);
1523 $res=Array();
1524 $i=-1;
1525 while(++$i<$len)
1526 $res[]=$temp[$keys[$i]];
1527 return $res;
1528 }
1529
1536 public function OutputHtmlOnRequest($andExit=true){
1537 if(!$this->IsHtmlRequested())
1538 return false;
1539 $this->OutputHtml();
1540 if($andExit){
1541 self::Debug('Exit script execution');
1542 exit;
1543 }
1544 return true;
1545 }
1546
1556 public function OutputPhp($withHeaders=true,$echo=true,$options=Array(),$cache=true){
1557 self::Debug('Output PHP');
1558 if(sizeof($this->Methods)<1)
1559 $this->CreateWsdl();
1560 if(!self::CallHook(
1561 'OutputPhpHook',
1562 Array(
1563 'server' => $this,
1564 'withHeaders' => &$withHeaders,
1565 'echo' => &$echo,
1566 'options' => &$options
1567 )
1568 )
1569 )
1570 return '';
1571 // Options
1572 $hasOptions=sizeof(array_keys($options))>0;
1573 if(!isset($options['class']))
1574 $options['class']=$this->Name.'SoapClient';
1575 if(!isset($options['openphp']))
1576 $options['openphp']=true;
1577 if(!isset($options['phpclient']))
1578 $options['phpclient']=true;
1579 $data=Array(
1580 'server' => $this,
1581 'withHeaders' => &$withHeaders,
1582 'echo' => &$echo,
1583 'options' => &$options,
1584 'res' => &$res
1585 );
1586 // Header
1587 if($withHeaders){
1588 header('Content-Type: text/plain; charset=UTF-8',true);
1589 header('Content-Disposition: attachment; filename='.$options['class'].'.php');
1590 }
1591 if(!$hasOptions){
1592 if(is_null($this->PHP))
1593 $this->GetWsdlFromCache();
1594 if(!is_null($this->PHP)){
1595 if($echo)
1596 echo $this->PHP;
1597 return $this->PHP;
1598 }
1599 }else if(isset($options['php'])&&!is_null($options['php'])){
1600 echo $options['php'];
1601 return $options['php'];
1602 }
1603 $res=Array();
1604 if($options['openphp'])
1605 $res[]="<?php";
1606 $res[]="/**";
1607 if(!is_null($this->Docs)){
1608 $res[]=" * ".implode("\n * ",explode("\n",$this->Docs));
1609 $res[]=" *";
1610 }
1611 $res[]=" * @service ".$options['class'];
1612 $res[]=" */";
1613 $res[]="class ".$options['class']."{";
1614 $res[]="\t/**";
1615 $res[]="\t * The WSDL URI";
1616 $res[]="\t *";
1617 $res[]="\t * @var string";
1618 $res[]="\t */";
1619 $res[]="\tpublic static \$_WsdlUri='".(!is_null($this->WsdlUri)?$this->WsdlUri:$this->EndPoint.'?WSDL')."';";
1620 $res[]="\t/**";
1621 $res[]="\t * The PHP SoapClient object";
1622 $res[]="\t *";
1623 $res[]="\t * @var object";
1624 $res[]="\t */";
1625 $res[]="\tpublic static \$_Server=null;";
1626 self::CallHook('BeginCreatePhpHook',$data);
1627 $res[]='';
1628 $res[]="\t/**";
1629 $res[]="\t * Send a SOAP request to the server";
1630 $res[]="\t *";
1631 $res[]="\t * @param string \$method The method name";
1632 $res[]="\t * @param array \$param The parameters";
1633 $res[]="\t * @return mixed The server response";
1634 $res[]="\t */";
1635 $res[]="\tpublic static function _Call(\$method,\$param){";
1636 if(self::CallHook('CreatePhpCallHook',$data)){
1637 $res[]="\t\tif(is_null(self::\$_Server))";
1638 if($options['phpclient']){
1639 $res[]="\t\t\tself::\$_Server=new SoapClient(self::\$_WsdlUri);";
1640 $res[]="\t\treturn self::\$_Server->__soapCall(\$method,\$param);";
1641 }else{
1642 $res[]="\t\t\tself::\$_Server=new PhpWsdlClient(self::\$_WsdlUri);";
1643 $res[]="\t\treturn self::\$_Server->DoRequest(\$method,\$param);";
1644 }
1645 }
1646 $res[]="\t}";
1647 // Methods
1648 $i=-1;
1649 $len=sizeof($this->Methods);
1650 while(++$i<$len){
1651 $res[]='';
1652 $this->Methods[$i]->CreateMethodPhp($data);
1653 }
1654 $res[]="}";
1655 // Types
1656 $i=-1;
1657 $len=sizeof($this->Types);
1658 while(++$i<$len){
1659 $res[]='';
1660 $this->Types[$i]->CreateTypePhp($data);
1661 }
1662 self::CallHook('EndCreatePhpHook',$data);
1663 $res=implode("\n",$res);
1664 if(!$hasOptions){
1665 if(is_null($this->PHP))
1666 $this->PHP=$res;
1667 if($cache)
1668 $this->WriteWsdlToCache(null,null,null,true);
1669 }
1670 if($echo)
1671 echo $res;
1672 return $res;
1673 }
1674
1681 public function OutputPhpOnRequest($andExit=true){
1682 if(!$this->IsPhpRequested())
1683 return false;
1684 $this->OutputPhp();
1685 if($andExit){
1686 self::Debug('Exit script execution');
1687 exit;
1688 }
1689 return true;
1690 }
1691
1701 public function RunServer($wsdlFile=null,$class=null,$andExit=true,$forceNoWsdl=false){
1702 self::Debug('Run the server');
1703 if($forceNoWsdl)
1704 self::Debug('Forced non-WSDL mode');
1705 if(self::CallHook(
1706 'BeforeRunServerHook',
1707 Array(
1708 'server' => $this,
1709 'wsdlfile' => &$wsdlFile,
1710 'class' => &$class,
1711 'andexit' => &$andExit,
1712 'forcenowsdl' => &$forceNoWsdl
1713 )
1714 )
1715 ){
1716 // WSDL requested?
1717 if($this->OutputWsdlOnRequest($andExit))
1718 return false;
1719 // PHP requested?
1720 if($this->OutputPhpOnRequest($andExit))
1721 return false;
1722 // HTML requested?
1723 if($this->OutputHtmlOnRequest($andExit))
1724 return false;
1725 }
1726 // Login
1727 $user=null;
1728 $password=null;
1729 if($this->RequireLogin){
1730 if(isset($_SERVER['PHP_AUTH_USER'])||isset($_SERVER['PHP_AUTH_PW'])){
1731 $user=(isset($_SERVER['PHP_AUTH_USER']))?$_SERVER['PHP_AUTH_USER']:null;
1732 $password=(isset($_SERVER['PHP_AUTH_PW']))?$_SERVER['PHP_AUTH_PW']:null;
1733 }
1734 self::Debug('Check login '.$user.':'.str_repeat('*',strlen($password)));
1735 if(!self::CallHook(
1736 'LoginHook',
1737 Array(
1738 'server' => $this,
1739 'user' => &$user,
1740 'password' => &$password
1741 )
1742 )
1743 ){
1744 self::Debug('Login required');
1745 header('WWW-Authenticate: Basic realm="SOAP webservice login required"');
1746 header('HTTP/1.0 401 Unauthorized');
1747 if($andExit){
1748 self::Debug('Exit script execution');
1749 exit;
1750 }
1751 return false;
1752 }
1753 }
1754 // Load the proxy
1755 $useProxy=false;
1756 if(is_array($class)){
1757 self::Debug('Use the proxy for '.$class[0]);
1758 self::$ProxyObject=$class[1];
1759 self::$ProxyServer=$this;
1760 $class=$class[0];
1761 $useProxy=true;
1762 }
1763 // Ensure a webservice name
1764 if(is_null($class)){
1765 self::Debug('No webservice name yet');
1766 if(!$this->DetermineConfiguration())
1767 throw(new Exception('Invalid configuration'));
1768 if(!is_null($this->Name))
1769 $class=$this->Name;
1770 }else if(is_string($class)){
1771 self::Debug('Using '.$class.' as webservice name');
1772 $this->Name=$class;
1773 }
1774 self::Debug('Use class '.((!is_object($class))?$class:get_class($class)));
1775 // Load WSDL
1776 if(!$forceNoWsdl&&(!$useProxy||self::$UseProxyWsdl)){
1777 self::Debug('Load WSDL');
1778 $this->CreateWsdl(false,true);
1779 if(is_null($wsdlFile))
1780 $wsdlFile=$this->GetCacheFileName();
1781 if(!is_null($wsdlFile))
1782 if(!file_exists($wsdlFile)){
1783 self::Debug('WSDL file "'.$wsdlFile.'" does not exists');
1784 $wsdlFile=null;
1785 }
1786 }
1787 // Load the files, if the webservice handler class doesn't exist
1788 if(!is_object($class))
1789 if(!class_exists($class)&&!$this->IsOnlyGlobal()){
1790 self::Debug('Try to load the webservice handler class');
1791 $i=-1;
1792 $len=sizeof($this->Files);
1793 while(++$i<$len){
1794 self::Debug('Load '.$this->Files[$i]);
1795 require_once($this->Files[$i]);
1796 }
1797 if(!class_exists($class)){
1798 // Try class.webservice.php
1799 if(file_exists('class.webservice.php')){
1800 self::Debug('Try to load class.webservice.php');
1801 require_once('class.webservice.php');
1802 if(class_exists($class))
1803 $this->Files[]='class.webservice.php';
1804 }
1805 if(!class_exists($class))
1806 if(file_exists(dirname(__FILE__).'/class.webservice.php')){
1807 self::Debug('Try to load '.dirname(__FILE__).'/class.webservice.php');
1808 require_once(dirname(__FILE__).'/class.webservice.php');
1809 if(class_exists($class))
1810 $this->Files[]=dirname(__FILE__).'/class.webservice.php';
1811 }
1812 if(!class_exists($class))
1813 // A handler class or object is required when using non-global methods!
1814 throw(new Exception('Webservice handler class not present'));
1815 }
1816 }
1817 // Prepare the SOAP server
1818 $this->SoapServer=null;
1819 if(self::CallHook(
1820 'PrepareServerHook',
1821 Array(
1822 'server' => $this,
1823 'soapserver' => &$this->SoapServer,
1824 'wsdlfile' => &$wsdlFile,
1825 'class' => &$class,
1826 'useproxy' => &$useProxy,
1827 'forcenowsdl' => &$forceNoWsdl,
1828 'andexit' => &$andExit,
1829 'user' => &$user,
1830 'password' => &$password
1831 )
1832 )
1833 ){
1834 self::Debug('Prepare the SOAP server');
1835 // WSDL file
1836 $wsdlFile=($forceNoWsdl||($useProxy&&!self::$UseProxyWsdl))?null:$wsdlFile;
1837 if(!is_null($wsdlFile)){
1838 self::Debug('Using WSDL file '.$wsdlFile);
1839 }else{
1840 self::Debug('No WSDL file');
1841 }
1842 // Server options
1843 $temp=Array(
1844 'actor' => $this->EndPoint,
1845 'uri' => $this->NameSpace,
1846 );
1847 $temp=array_merge($this->SoapServerOptions,$temp);
1848 if(self::$Debugging)
1849 self::Debug('Server options: '.print_r($temp,true));
1850 // Create the server object
1851 self::Debug('Creating PHP SoapServer object');
1852 $this->SoapServer=new webServicesServer(
1853 $wsdlFile,
1854 $temp
1855 );
1856 // Set the handler class or object
1857 if($useProxy||!is_object($class)){
1858 $temp=($useProxy)?'PhpWsdlProxy':$class;
1859 if(!is_null($temp)){
1860 self::Debug('Setting server class '.$temp);
1861 $this->SoapServer->setClass($temp);
1862 }else{
1863 self::Debug('No server class or object');
1864 }
1865 }else{
1866 self::Debug('Setting server object '.get_class($class));
1867 $this->SoapServer->setObject($class);
1868 }
1869 // Add global methods
1870 $i=-1;
1871 $len=sizeof($this->Methods);
1872 while(++$i<$len)
1873 if($this->Methods[$i]->IsGlobal){
1874 self::Debug('Adding global method '.$this->Methods[$i]->Name);
1875 $this->SoapServer->addFunction($this->Methods[$i]->Name);
1876 }
1877 }
1878 // Run the SOAP server
1879 if(self::CallHook(
1880 'RunServerHook',
1881 Array(
1882 'server' => $this,
1883 'soapserver' => &$this->SoapServer,
1884 'wsdlfile' => &$wsdlFile,
1885 'class' => &$class,
1886 'useproxy' => &$useProxy,
1887 'forcenowsdl' => &$forceNoWsdl,
1888 'andexit' => &$andExit,
1889 'user' => &$user,
1890 'password' => &$password
1891 )
1892 )
1893 ){
1894 self::Debug('Run the SOAP server');
1895 $this->SoapServer->handle();
1896 if($andExit){
1897 self::Debug('Exit script execution');
1898 exit;
1899 }
1900 }
1901 return true;
1902 }
1903
1909 public function GetWsdlUri(){
1910 return ((is_null($this->WsdlUri))?$this->EndPoint:$this->WsdlUri).'?WSDL';
1911 }
1912
1918 public function GetPhpUri(){
1919 return ((is_null($this->PhpUri))?$this->EndPoint:$this->PhpUri).'?PHPSOAPCLIENT';
1920 }
1921
1927 public function GetDocUri(){
1928 return (is_null($this->PhpUri))?$this->EndPoint:$this->DocUri;
1929 }
1930
1937 public function GetMethod($name){
1938 self::Debug('Find method '.$name);
1939 $i=-1;
1940 $len=sizeof($this->Methods);
1941 while(++$i<$len)
1942 if($this->Methods[$i]->Name==$name){
1943 self::Debug('Found method at index '.$i);
1944 return $this->Methods[$i];
1945 }
1946 return null;
1947 }
1948
1955 public function GetType($name){
1956 self::Debug('Find type '.$name);
1957 $i=-1;
1958 $len=sizeof($this->Types);
1959 while(++$i<$len)
1960 if($this->Types[$i]->Name==$name){
1961 self::Debug('Found type at index '.$i);
1962 return $this->Types[$i];
1963 }
1964 return null;
1965 }
1966
1973 public function GetCacheFileName($endpoint=null){
1974 $data=Array(
1975 'server' => $this,
1976 'endpoint' => $endpoint,
1977 'filename' => (is_null(self::$CacheFolder))?null:self::$CacheFolder.'/'.sha1((is_null($endpoint))?$this->EndPoint:$endpoint).'.wsdl'
1978 );
1980 'CacheFileNameHook',
1981 $data
1982 );
1983 return $data['filename'];
1984 }
1985
1992 public function CacheFileExists($file=null){
1993 if(is_null($file))
1994 $file=$this->GetCacheFileName();
1995 self::Debug('Check cache file exists '.$file);
1996 return file_exists($file)&&file_exists($file.'.cache');
1997 }
1998
2005 public function IsCacheValid($file=null){
2006 self::Debug('Check cache valid');
2007 if(is_null($file))
2008 $file=$this->GetCacheFileName();
2009 if(!$this->CacheFileExists($file))
2010 return false;
2011 return self::$CacheTime<0||time()-file_get_contents($file.'.cache')<=self::$CacheTime;
2012 }
2013
2022 public function GetWsdlFromCache($file=null,$force=false,$nounserialize=false){
2023 self::Debug('Get WSDL from cache');
2024 if(!is_null($this->WSDL))
2025 return $this->WSDL;
2026 if(is_null($file))
2027 $file=$this->GetCacheFileName();
2028 if(!$force){
2029 if(!$this->IsCacheValid($file))
2030 return null;
2031 }else if(!$this->CacheFileExists($file)){
2032 return null;
2033 }
2034 $this->WSDL=file_get_contents($file);
2035 if(!$nounserialize){
2036 self::Debug('Unserialize methods, types and files');
2037 $data=unserialize(file_get_contents($file.'.obj'));
2038 $this->Methods=$data['methods'];
2039 $this->Types=$data['types'];
2040 $this->Files=$data['files'];
2041 $this->Name=$data['name'];
2042 $this->Docs=$data['docs'];
2043 $this->HTML=$data['html'];
2044 $this->PHP=$data['php'];
2045 $this->WsdlUri=$data['wsdluri'];
2046 $this->PhpUri=$data['phpuri'];
2047 $this->DocUri=$data['docuri'];
2049 'ReadCacheHook',
2050 Array(
2051 'server' => $this,
2052 'data' => &$data
2053 )
2054 );
2055 if($data['version']!=self::$VERSION){
2056 self::Debug('Could not use cache from version '.$data['version']);
2057 $this->Methods=Array();
2058 $this->Types=Array();
2059 $this->Files=Array();
2060 $this->Name=null;
2061 $this->Docs=null;
2062 $this->HTML=null;
2063 $this->PHP=null;
2064 $this->WsdlUri=null;
2065 $this->PhpUri=null;
2066 $this->DocUri=null;
2067 $this->WSDL=null;
2068 $this->TidyCacheFolder(true);
2069 return null;
2070 }
2071 }
2072 $this->ConfigurationDetermined=true;
2073 $this->SourcesParsed=true;
2074 return $this->WSDL;
2075 }
2076
2086 public function WriteWsdlToCache($wsdl=null,$endpoint=null,$file=null,$force=false){
2087 self::Debug('Write WSDL to the cache');
2088 if(is_null($endpoint))
2089 $endpoint=$this->EndPoint;
2090 if($endpoint==$this->EndPoint&&!is_null($wsdl))
2091 $this->WSDL=$wsdl;
2092 if(is_null($wsdl)){
2093 if(is_null($this->WSDL)){
2094 self::Debug('No WSDL');
2095 return false;// WSDL not defined
2096 }
2097 $wsdl=$this->WSDL;
2098 }
2099 if(is_null($file)){
2100 $file=$this->GetCacheFileName($endpoint);
2101 if(is_null($file)){
2102 self::Debug('No cache file');
2103 return false;// No cache file
2104 }
2105 }
2106 $temp=substr($file,0,1);
2107 if($temp!='/'&&$temp!='.'){
2108 if(is_null(self::$CacheFolder)){
2109 self::Debug('No cache folder');
2110 return false;// No cache folder
2111 }
2112 $file=self::$CacheFolder.'/'.$file;
2113 }
2114 if(!$force)
2115 if($this->IsCacheValid($file)){
2116 self::Debug('Cache is still valid');
2117 return true;// Existing cache is still valid
2118 }
2119 self::Debug('Write to '.$file);
2120 if(file_put_contents($file,$wsdl)===false){
2121 self::Debug('Could not write to cache');
2122 return false;// Error writing to cache
2123 }
2124 if(file_put_contents($file.'.cache',time())===false){
2125 self::Debug('Could not write cache time file');
2126 return false;// Error writing to cache
2127 }
2128 $data=Array(
2129 'version' => self::$VERSION,
2130 'methods' => $this->Methods,
2131 'types' => $this->Types,
2132 'files' => $this->Files,
2133 'name' => $this->Name,
2134 'docs' => $this->Docs,
2135 'html' => $this->HTML,
2136 'php' => $this->PHP,
2137 'wsdluri' => $this->WsdlUri,
2138 'phpuri' => $this->PhpUri,
2139 'docuri' => $this->DocUri
2140 );
2142 'WriteCacheHook',
2143 Array(
2144 'server' => $this,
2145 'data' => &$data
2146 )
2147 );
2148 if(file_put_contents($file.'.obj',serialize($data))===false){
2149 self::Debug('Could not write serialized cache');
2150 return false;// Error writing to cache
2151 }
2152 return true;
2153 }
2154
2161 public static function IsCacheFolderWriteAble($folder=null){
2162 if(!is_null(self::$CacheFolderWriteAble))
2164 if(is_null($folder))
2165 $folder=self::$CacheFolder;
2166 if(is_null($folder)){
2167 self::$CacheFolderWriteAble=false;
2168 return false;
2169 }
2170 if(!is_dir($folder)){
2171 self::Debug('Invalid cache folder (not a directory?)');
2172 self::$CacheFolderWriteAble=false;
2173 return;
2174 }
2175 $file=uniqid();
2176 while(file_exists($folder.'/'.$file))
2177 $file=uniqid();
2178 $file=$folder.'/'.$file;
2179 $temp=uniqid();
2180 if(file_put_contents($file,$temp)===false){
2181 self::$CacheFolderWriteAble=false;
2182 return false;
2183 }
2184 $res=file_get_contents($file)===$temp;
2185 unlink($file);
2186 self::$CacheFolderWriteAble=$res;
2187 return $res;
2188 }
2189
2196 public function IsCacheDifferent(){
2197 self::Debug('Determine if the cache is different from this instance');
2198 // Load the cache
2199 $temp=new PhpWsdl(null,$this->EndPoint);
2200 $temp->GetWsdlFromCache();
2201 if(is_null($temp->WSDL))
2202 return true;// Not cached yet
2203 // Initialize this instance
2204 $this->DetermineConfiguration();
2205 $this->ParseSource();
2206 // Compare the cache with this instance
2207 $res=serialize(
2208 Array(
2209 $this->Methods,
2210 $this->Types
2211 )
2212 )!=serialize(
2213 Array(
2214 $temp->Methods,
2215 $temp->Types
2216 )
2217 );
2218 self::Debug('Cache is '.(($res)?'equal':'different'));
2219 return $res;
2220 }
2221
2230 public function TidyCacheFolder($mineOnly=false,$cleanUp=false,$wsdlFile=null){
2231 if(is_null(self::$CacheFolder))
2232 return Array();
2233 $deleted=Array();
2234 if($cleanUp){
2235 self::Debug('Cleanup cache');
2236 }else if($mineOnly){
2237 self::Debug('Clean own cache');
2238 }else{
2239 self::Debug('Clean all cache');
2240 }
2241 if($mineOnly){
2242 self::Debug('Delete own cache');
2243 $file=(is_null($wsdlFile))?$this->GetCacheFileName():$wsdlFile;
2244 if($cleanUp)
2245 if($this->IsCacheValid($file))
2246 return $deleted;
2247 if(file_exists($file))
2248 if(unlink($file))
2249 $deleted[]=$file;
2250 if(file_exists($file.'.cache'))
2251 if(unlink($file.'.cache'))
2252 $deleted[]=$file.'.cache';
2253 if(file_exists($file.'.obj'))
2254 if(unlink($file.'.obj'))
2255 $deleted[]=$file.'.obj';
2256 self::Debug(sizeof($deleted).' files deleted');
2257 }else{
2258 self::Debug('Delete whole cache');
2259 $files=glob(self::$CacheFolder.(($cleanUp)?'/*.wsdl':'/*.wsd*'));
2260 if($files!==false){
2261 $toDelete=Array();
2262 $i=-1;
2263 $len=sizeof($files);
2264 while(++$i<$len){
2265 $file=$files[$i];
2266 if($cleanUp){
2267 if(!$this->IsCacheValid($file))
2268 continue;
2269 $toDelete[]=$file;
2270 $toDelete[]=$file.'.cache';
2271 $toDelete[]=$file.'.obj';
2272 }else{
2273 if(!preg_match('/\.wsdl(\.cache|\.obj)?$/',$file))
2274 continue;
2275 if(unlink($files[$i]))
2276 $deleted[]=$files[$i];
2277 }
2278 }
2279 if($cleanUp){
2280 $i=-1;
2281 $len=sizeof($toDelete);
2282 while(++$i<$len)
2283 if(file_exists($toDelete[$i]))
2284 if(unlink($toDelete[$i]))
2285 $deleted[]=$toDelete[$i];
2286 }
2287 self::Debug(sizeof($deleted).' files deleted');
2288 }else{
2289 self::Debug('"glob" failed');
2290 }
2291 }
2292 return $deleted;
2293 }
2294
2301 public static function TranslateType($type){
2302 if(!self::CallHook(
2303 'TranslateTypeHook',
2304 Array(
2305 'type' => &$type
2306 )
2307 )
2308 )
2309 return $type;
2310 return ((in_array($type,self::$BasicTypes))?self::$Config['xsd']:self::$Config['tns']).':'.$type;
2311 }
2312
2320 public static function CallHook($name,$data=null){
2321 self::Debug('Call hook '.$name);
2322 if(!self::HasHookHandler($name))
2323 return true;
2324 $keys=array_keys(self::$Config['extensions'][$name]);
2325 $i=-1;
2326 $len=sizeof($keys);
2327 while(++$i<$len){
2328 self::Debug('Call '.self::$Config['extensions'][$name][$keys[$i]]);
2329 if(!call_user_func(self::$Config['extensions'][$name][$keys[$i]],$data)){
2330 self::Debug('Handler stopped hook execution');
2331 return false;
2332 }
2333 }
2334 return true;
2335 }
2336
2344 public static function RegisterHook($hook,$name,$data){
2345 if(!self::HasHookHandler($hook))
2346 self::$Config['extensions'][$hook]=Array();
2347 if(self::$Debugging){
2348 $handler=$data;
2349 if(is_array($handler)){
2350 $class=$handler[0];
2351 $method=$handler[1];
2352 if(is_object($class))
2353 $class=get_class($class);
2354 $handler=$class.'.'.$method;
2355 }
2356 self::Debug('Register hook '.$hook.' handler '.$name.': '.$handler);
2357 }
2358 self::$Config['extensions'][$hook][$name]=$data;
2359 }
2360
2367 public static function UnregisterHook($hook,$name=null){
2368 if(!self::HasHookHandler($hook))
2369 return;
2370 if(!is_null($name)){
2371 if(!isset(self::$Config['extensions'][$hook][$name]))
2372 return;
2373 }else{
2374 unset(self::$Config['extensions'][$hook]);
2375 return;
2376 }
2377 unset(self::$Config['extensions'][$hook][$name]);
2378 if(self::$Debugging)
2379 self::Debug('Unregister hook '.$hook.' handler '.$name);
2380 if(sizeof(self::$Config['extensions'][$hook])<1)
2381 unset(self::$Config['extensions'][$hook]);
2382 }
2383
2390 public static function HasHookHandler($hook){
2391 return isset(self::$Config['extensions'][$hook]);
2392 }
2393
2399 public static function Debug($str){
2400 if(!self::$Debugging)
2401 return;
2402 $temp=date('Y-m-d H:i:s')."\t".$str;
2403 if(self::$DebugBackTrace){
2404 $trace=debug_backtrace();
2405 $temp.=" ('".$trace[1]['function']."' in '".basename($trace[1]['file'])."' at line #".$trace[1]['line'].")";
2406 }
2407 self::$DebugInfo[]=$temp;
2408 if(!is_null(self::$DebugFile))
2409 if(file_put_contents(self::$DebugFile,$temp."\n",FILE_APPEND)===false){
2410 self::Debug('Could not write to debug file '.self::$DebugFile);
2411 self::$DebugFile=null;
2412 }
2413 }
2414
2418 public static function Init(){
2419 self::Debug('Init');
2420 // Configuration
2421 self::$HTML2PDFSettings=Array(
2422 'attachments' => '1',
2423 'outline' => '1'
2424 );
2425 self::$NameSpaces=Array(
2426 'soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
2427 's' => 'http://www.w3.org/2001/XMLSchema',
2428 'wsdl' => 'http://schemas.xmlsoap.org/wsdl/',
2429 'soapenc' => 'http://schemas.xmlsoap.org/soap/encoding/'
2430 );
2432 self::$Config['extensions']=Array();// A configuration space for extensions
2433 self::$Config['tns']='tns'; // The xmlns name for the target namespace
2434 self::$Config['xsd']='s'; // The xmlns name for the XSD namespace
2435 // Parser hooks
2436 self::RegisterHook('InterpretKeywordserviceHook','internal','PhpWsdl::InterpretService');
2437 // WSDL hooks
2438 self::RegisterHook('CreateWsdlHeaderHook','internal','PhpWsdl::CreateWsdlHeader');
2439 self::RegisterHook('CreateWsdlTypeSchemaHook','internal','PhpWsdl::CreateWsdlTypeSchema');
2440 self::RegisterHook('CreateWsdlMessagesHook','internal','PhpWsdl::CreateWsdlMessages');
2441 self::RegisterHook('CreateWsdlPortsHook','internal','PhpWsdl::CreateWsdlPorts');
2442 self::RegisterHook('CreateWsdlBindingsHook','internal','PhpWsdl::CreateWsdlBindings');
2443 self::RegisterHook('CreateWsdlServiceHook','internal','PhpWsdl::CreateWsdlService');
2444 self::RegisterHook('CreateWsdlFooterHook','internal','PhpWsdl::CreateWsdlFooter');
2445 self::RegisterHook('CreateWsdlOptimizeHook','internal','PhpWsdl::CreateWsdlOptimize');
2446 // HTML hooks
2447 self::RegisterHook('CreateHtmlGeneralHook','internal','PhpWsdl::CreateHtmlGeneral');
2448 self::RegisterHook('CreateHtmlIndexHook','internal','PhpWsdl::CreateHtmlIndex');
2449 self::RegisterHook('CreateHtmlMethodsHook','internal','PhpWsdl::CreateHtmlMethods');
2450 self::RegisterHook('CreateHtmlComplexTypesHook','internal','PhpWsdl::CreateHtmlComplexTypes');
2451 // Extensions
2452 self::Debug('Load extensions');
2453 $files=glob(dirname(__FILE__).'/'.'class.phpwsdl.*.php');
2454 if($files!==false){
2455 $i=-1;
2456 $len=sizeof($files);
2457 while(++$i<$len){
2458 self::Debug('Load '.$files[$i]);
2459 require_once($files[$i]);
2460 }
2461 }else{
2462 self::Debug('"glob" failed');
2463 }
2464 }
2465
2469 public static function PostInit(){
2470 self::CallHook('PostInitHook');
2471 // Autorun
2472 global $PhpWsdlAutoRun;
2473 if(self::$AutoRun||$PhpWsdlAutoRun)
2475 }
2476}
DetermineEndPoint()
OutputPhpOnRequest($andExit=true)
CacheFileExists($file=null)
static InterpretService($data)
ParseSource($init=false, $str=null)
static $AutoRun
static $HTML2PDFLicenseKey
GetType($name)
static CreateWsdlService($data)
OutputWsdl($withHeaders=true)
IsFileInList($file)
static CreateWsdlPorts($data)
static $VERSION
TidyCacheFolder($mineOnly=false, $cleanUp=false, $wsdlFile=null)
GetCacheFileName($endpoint=null)
GetMethod($name)
static $CacheFolder
DetermineNameSpace()
static Debug($str)
static $NonNillable
static $DebugBackTrace
static $ProxyObject
static EnableCache($folder=null, $timeout=null)
static $CacheTime
static CreateHtmlMethods($data)
static CreateWsdlFooter($data)
static RegisterHook($hook, $name, $data)
__construct( $nameSpace=null, $endPoint=null, $cacheFolder=null, $file=null, $name=null, $methods=null, $types=null, $outputOnRequest=false, $runServer=false)
static $classRx
PhpWsdl( $nameSpace=null, $endPoint=null, $cacheFolder=null, $file=null, $name=null, $methods=null, $types=null, $outputOnRequest=false, $runServer=false)
static $Debugging
static CreateInstance( $nameSpace=null, $endPoint=null, $cacheFolder=null, $file=null, $name=null, $methods=null, $types=null, $outputOnRequest=false, $runServer=false)
OutputHtmlOnRequest($andExit=true)
CreateWsdl($reCreate=false, $optimizer=false)
static TranslateType($type)
static OptimizeXml($xml)
static CreateHtmlIndex($data)
SortObjectsByName($obj)
static CreateWsdlHeader($data)
static $HTML2PDFSettings
static $CacheFolderWriteAble
static $HTML2PDFAPI
static CreateHtmlGeneral($data)
static $DebugInfo
static CreateHtmlComplexTypes($data)
static $NameSpaces
static UnregisterHook($hook, $name=null)
RunServer($wsdlFile=null, $class=null, $andExit=true, $forceNoWsdl=false)
static CreateWsdlMessages($data)
$ConfigurationDetermined
static RunQuickMode($file=null)
static HasHookHandler($hook)
DetermineConfiguration()
WriteWsdlToCache($wsdl=null, $endpoint=null, $file=null, $force=false)
static CreateWsdlOptimize($data)
static DisableCache($allCaching=true)
static $Config
static CreateWsdlBindings($data)
static $BasicTypes
static $UseProxyWsdl
static $DebugFile
static $ProxyServer
IsCacheValid($file=null)
static CallHook($name, $data=null)
OutputWsdlOnRequest($andExit=true)
static $CacheAllWsdl
GetWsdlFromCache($file=null, $force=false, $nounserialize=false)
OutputHtml($withHeaders=true, $echo=true, $cache=true)
static IsCacheFolderWriteAble($folder=null)
OutputPhp($withHeaders=true, $echo=true, $options=Array(), $cache=true)
static FormatXml($xml)
static CreateWsdlTypeSchema($data)
$PhpWsdlAutoRun
Definição demo4.php:6