diff --git a/.cvsignore b/.cvsignore index 561ab7a607a819872e7c1b0ed146eadf75e2392e..d3f1850fa973a9f2e8d09a7d83c9bc95faf290b1 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,3 +1,3 @@ -index.php -documents -*.htaccess +index.php +documents +*.htaccess diff --git a/build/pad/Dolibarr developpers.cml b/build/pad/Dolibarr developpers.cml index 145e00011cb0322e695b8c835271c68de5ec9166..c925bd71fc28dcadd0b48cc296621c636f921dba 100644 --- a/build/pad/Dolibarr developpers.cml +++ b/build/pad/Dolibarr developpers.cml @@ -1,31 +1,31 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<PADGEN_CML> - <AppVerInfo>PADGen 2.0.2.30</AppVerInfo> - <Company_Info> - <Company_Name>Dolibarr Developpers</Company_Name> - <Address_1 /> - <Address_2 /> - <City_Town>Paris</City_Town> - <State_Province /> - <Zip_Postal_Code /> - <Country>FRANCE</Country> - <Company_WebSite_URL>http://www.dolibarr.org</Company_WebSite_URL> - <Contact_Info> - <Author_First_Name>Dolibarr team</Author_First_Name> - <Author_Last_Name>Dolibarr team</Author_Last_Name> - <Author_Email>dolibarr-dev@nongnu.org</Author_Email> - <Contact_First_Name>Dolibarr team</Contact_First_Name> - <Contact_Last_Name>Dolibarr team</Contact_Last_Name> - <Contact_Email>dolibarr-dev@nongnu.org</Contact_Email> - </Contact_Info> - <Support_Info> - <Sales_Email>dolibarr-dev@nongnu.org</Sales_Email> - <Support_Email>dolibarr-dev@nongnu.org</Support_Email> - <General_Email>dolibarr-dev@nongnu.org</General_Email> - <Sales_Phone /> - <Support_Phone /> - <General_Phone /> - <Fax_Phone /> - </Support_Info> - </Company_Info> -</PADGEN_CML> +<?xml version="1.0" encoding="UTF-8" ?> +<PADGEN_CML> + <AppVerInfo>PADGen 2.0.2.30</AppVerInfo> + <Company_Info> + <Company_Name>Dolibarr Developpers</Company_Name> + <Address_1 /> + <Address_2 /> + <City_Town>Paris</City_Town> + <State_Province /> + <Zip_Postal_Code /> + <Country>FRANCE</Country> + <Company_WebSite_URL>http://www.dolibarr.org</Company_WebSite_URL> + <Contact_Info> + <Author_First_Name>Dolibarr team</Author_First_Name> + <Author_Last_Name>Dolibarr team</Author_Last_Name> + <Author_Email>dolibarr-dev@nongnu.org</Author_Email> + <Contact_First_Name>Dolibarr team</Contact_First_Name> + <Contact_Last_Name>Dolibarr team</Contact_Last_Name> + <Contact_Email>dolibarr-dev@nongnu.org</Contact_Email> + </Contact_Info> + <Support_Info> + <Sales_Email>dolibarr-dev@nongnu.org</Sales_Email> + <Support_Email>dolibarr-dev@nongnu.org</Support_Email> + <General_Email>dolibarr-dev@nongnu.org</General_Email> + <Sales_Phone /> + <Support_Phone /> + <General_Phone /> + <Fax_Phone /> + </Support_Info> + </Company_Info> +</PADGEN_CML> diff --git a/build/pad/Dolibarr v2.0.pml b/build/pad/Dolibarr v2.0.pml index 95593e67bc51e6e30afa430548f7243b8583599e..1f89e0d15e82293d4aa69da0a3649e5a8732fa71 100644 --- a/build/pad/Dolibarr v2.0.pml +++ b/build/pad/Dolibarr v2.0.pml @@ -1,178 +1,178 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<PADGEN_PML> - <AppVerInfo>PADGen 2.0.2.30</AppVerInfo> - <CompanyName /> - <Program_Info> - <Program_Name>Dolibarr</Program_Name> - <Program_Version>2.1</Program_Version> - <Program_Release_Month>07</Program_Release_Month> - <Program_Release_Day>14</Program_Release_Day> - <Program_Release_Year>2006</Program_Release_Year> - <Program_Cost_Dollars>0</Program_Cost_Dollars> - <Program_Cost_Other_Code /> - <Program_Cost_Other>0</Program_Cost_Other> - <Program_Type>Freeware</Program_Type> - <Program_Release_Status>Major Update</Program_Release_Status> - <Program_Install_Support>Uninstall Only</Program_Install_Support> - <Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support> - <Program_Language>English,French</Program_Language> - <Program_Change_Info>http://www.dolibarr.org</Program_Change_Info> - <Program_Specific_Category>Business</Program_Specific_Category> - <Program_Category_Class>Business::Accounting & Finance</Program_Category_Class> - <Program_System_Requirements>None</Program_System_Requirements> - <File_Info> - <File_Size_Bytes>1016660</File_Size_Bytes> - <File_Size_K>992</File_Size_K> - <File_Size_MB>0.97</File_Size_MB> - </File_Info> - <Expire_Info> - <Has_Expire_Info>N</Has_Expire_Info> - <Expire_Count /> - <Expire_Based_On>Days</Expire_Based_On> - <Expire_Other_Info /> - <Expire_Month /> - <Expire_Day /> - <Expire_Year /> - </Expire_Info> - </Program_Info> - <Program_Descriptions> - <English> - <Keywords>dolibarr</Keywords> - <Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45> - <Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80> - <Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250> - <Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450> - <Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000> - </English> - <French> - <Keywords /> - <Char_Desc_45 /> - <Char_Desc_80 /> - <Char_Desc_250 /> - <Char_Desc_450 /> - <Char_Desc_2000 /> - </French> - </Program_Descriptions> - <Web_Info> - <Application_URLs> - <Application_Info_URL>http://www.dolibarr.org</Application_Info_URL> - <Application_Order_URL>http://www.dolibarr.org</Application_Order_URL> - <Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL> - <Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/dolibarr.ico</Application_Icon_URL> - <Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL> - </Application_URLs> - <Download_URLs> - <Primary_Download_URL /> - <Secondary_Download_URL /> - <Additional_Download_URL_1 /> - <Additional_Download_URL_2 /> - </Download_URLs> - </Web_Info> - <Permissions> - <Distribution_Permissions>GNU GPL</Distribution_Permissions> - <EULA>GNU GPL</EULA> - </Permissions> - <ASP> - <ASP_FORM>Y</ASP_FORM> - <ASP_Member>N</ASP_Member> - <ASP_Member_Number /> - </ASP> - <Affiliates> - <Affiliates_FORM>Y</Affiliates_FORM> - <Affiliates_VERSION>1.2</Affiliates_VERSION> - <Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL> - <Affiliates_Information_Page /> - <Affiliates_Avangate_Order_Page /> - <Affiliates_Avangate_Vendor_ID /> - <Affiliates_Avangate_Product_ID /> - <Affiliates_Avangate_Maximum_Commission_Rate /> - <Affiliates_BMTMicro_Order_Page /> - <Affiliates_BMTMicro_Vendor_ID /> - <Affiliates_BMTMicro_Product_ID /> - <Affiliates_BMTMicro_Maximum_Commission_Rate /> - <Affiliates_clixGalore_Order_Page /> - <Affiliates_clixGalore_Vendor_ID /> - <Affiliates_clixGalore_Product_ID /> - <Affiliates_clixGalore_Maximum_Commission_Rate /> - <Affiliates_CommissionJunction_Order_Page /> - <Affiliates_CommissionJunction_Vendor_ID /> - <Affiliates_CommissionJunction_Product_ID /> - <Affiliates_CommissionJunction_Maximum_Commission_Rate /> - <Affiliates_DigiBuy_Order_Page /> - <Affiliates_DigiBuy_Vendor_ID /> - <Affiliates_DigiBuy_Product_ID /> - <Affiliates_DigiBuy_Maximum_Commission_Rate /> - <Affiliates_DigitalCandle_Order_Page /> - <Affiliates_DigitalCandle_Vendor_ID /> - <Affiliates_DigitalCandle_Product_ID /> - <Affiliates_DigitalCandle_Maximum_Commission_Rate /> - <Affiliates_Emetrix_Order_Page /> - <Affiliates_Emetrix_Vendor_ID /> - <Affiliates_Emetrix_Product_ID /> - <Affiliates_Emetrix_Maximum_Commission_Rate /> - <Affiliates_eSellerate_Order_Page /> - <Affiliates_eSellerate_Vendor_ID /> - <Affiliates_eSellerate_Product_ID /> - <Affiliates_eSellerate_Maximum_Commission_Rate /> - <Affiliates_Kagi_Order_Page /> - <Affiliates_Kagi_Vendor_ID /> - <Affiliates_Kagi_Product_ID /> - <Affiliates_Kagi_Maximum_Commission_Rate /> - <Affiliates_LinkShare_Order_Page /> - <Affiliates_LinkShare_Vendor_ID /> - <Affiliates_LinkShare_Product_ID /> - <Affiliates_LinkShare_Maximum_Commission_Rate /> - <Affiliates_NorthStarSol_Order_Page /> - <Affiliates_NorthStarSol_Vendor_ID /> - <Affiliates_NorthStarSol_Product_ID /> - <Affiliates_NorthStarSol_Maximum_Commission_Rate /> - <Affiliates_Order1_Order_Page /> - <Affiliates_Order1_Vendor_ID /> - <Affiliates_Order1_Product_ID /> - <Affiliates_Order1_Maximum_Commission_Rate /> - <Affiliates_Osolis_Order_Page /> - <Affiliates_Osolis_Vendor_ID /> - <Affiliates_Osolis_Product_ID /> - <Affiliates_Osolis_Maximum_Commission_Rate /> - <Affiliates_Plimus_Order_Page /> - <Affiliates_Plimus_Vendor_ID /> - <Affiliates_Plimus_Product_ID /> - <Affiliates_Plimus_Maximum_Commission_Rate /> - <Affiliates_Regnet_Order_Page /> - <Affiliates_Regnet_Vendor_ID /> - <Affiliates_Regnet_Product_ID /> - <Affiliates_Regnet_Maximum_Commission_Rate /> - <Affiliates_Regnow_Order_Page /> - <Affiliates_Regnow_Vendor_ID /> - <Affiliates_Regnow_Product_ID /> - <Affiliates_Regnow_Maximum_Commission_Rate /> - <Affiliates_Regsoft_Order_Page /> - <Affiliates_Regsoft_Vendor_ID /> - <Affiliates_Regsoft_Product_ID /> - <Affiliates_Regsoft_Maximum_Commission_Rate /> - <Affiliates_ShareIt_Order_Page /> - <Affiliates_ShareIt_Vendor_ID /> - <Affiliates_ShareIt_Product_ID /> - <Affiliates_ShareIt_Maximum_Commission_Rate /> - <Affiliates_Shareasale_Order_Page /> - <Affiliates_Shareasale_Vendor_ID /> - <Affiliates_Shareasale_Product_ID /> - <Affiliates_Shareasale_Maximum_Commission_Rate /> - <Affiliates_SWReg_Order_Page /> - <Affiliates_SWReg_Vendor_ID /> - <Affiliates_SWReg_Product_ID /> - <Affiliates_SWReg_Maximum_Commission_Rate /> - <Affiliates_V-Share_Order_Page /> - <Affiliates_V-Share_Vendor_ID /> - <Affiliates_V-Share_Product_ID /> - <Affiliates_V-Share_Maximum_Commission_Rate /> - <Affiliates_VFree_Order_Page /> - <Affiliates_VFree_Vendor_ID /> - <Affiliates_VFree_Product_ID /> - <Affiliates_VFree_Maximum_Commission_Rate /> - <Affiliates_Yaskifo_Order_Page /> - <Affiliates_Yaskifo_Vendor_ID /> - <Affiliates_Yaskifo_Product_ID /> - <Affiliates_Yaskifo_Maximum_Commission_Rate /> - </Affiliates> -</PADGEN_PML> +<?xml version="1.0" encoding="UTF-8" ?> +<PADGEN_PML> + <AppVerInfo>PADGen 2.0.2.30</AppVerInfo> + <CompanyName /> + <Program_Info> + <Program_Name>Dolibarr</Program_Name> + <Program_Version>2.1</Program_Version> + <Program_Release_Month>07</Program_Release_Month> + <Program_Release_Day>14</Program_Release_Day> + <Program_Release_Year>2006</Program_Release_Year> + <Program_Cost_Dollars>0</Program_Cost_Dollars> + <Program_Cost_Other_Code /> + <Program_Cost_Other>0</Program_Cost_Other> + <Program_Type>Freeware</Program_Type> + <Program_Release_Status>Major Update</Program_Release_Status> + <Program_Install_Support>Uninstall Only</Program_Install_Support> + <Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support> + <Program_Language>English,French</Program_Language> + <Program_Change_Info>http://www.dolibarr.org</Program_Change_Info> + <Program_Specific_Category>Business</Program_Specific_Category> + <Program_Category_Class>Business::Accounting & Finance</Program_Category_Class> + <Program_System_Requirements>None</Program_System_Requirements> + <File_Info> + <File_Size_Bytes>1016660</File_Size_Bytes> + <File_Size_K>992</File_Size_K> + <File_Size_MB>0.97</File_Size_MB> + </File_Info> + <Expire_Info> + <Has_Expire_Info>N</Has_Expire_Info> + <Expire_Count /> + <Expire_Based_On>Days</Expire_Based_On> + <Expire_Other_Info /> + <Expire_Month /> + <Expire_Day /> + <Expire_Year /> + </Expire_Info> + </Program_Info> + <Program_Descriptions> + <English> + <Keywords>dolibarr</Keywords> + <Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45> + <Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80> + <Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250> + <Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450> + <Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000> + </English> + <French> + <Keywords /> + <Char_Desc_45 /> + <Char_Desc_80 /> + <Char_Desc_250 /> + <Char_Desc_450 /> + <Char_Desc_2000 /> + </French> + </Program_Descriptions> + <Web_Info> + <Application_URLs> + <Application_Info_URL>http://www.dolibarr.org</Application_Info_URL> + <Application_Order_URL>http://www.dolibarr.org</Application_Order_URL> + <Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL> + <Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/dolibarr.ico</Application_Icon_URL> + <Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL> + </Application_URLs> + <Download_URLs> + <Primary_Download_URL /> + <Secondary_Download_URL /> + <Additional_Download_URL_1 /> + <Additional_Download_URL_2 /> + </Download_URLs> + </Web_Info> + <Permissions> + <Distribution_Permissions>GNU GPL</Distribution_Permissions> + <EULA>GNU GPL</EULA> + </Permissions> + <ASP> + <ASP_FORM>Y</ASP_FORM> + <ASP_Member>N</ASP_Member> + <ASP_Member_Number /> + </ASP> + <Affiliates> + <Affiliates_FORM>Y</Affiliates_FORM> + <Affiliates_VERSION>1.2</Affiliates_VERSION> + <Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL> + <Affiliates_Information_Page /> + <Affiliates_Avangate_Order_Page /> + <Affiliates_Avangate_Vendor_ID /> + <Affiliates_Avangate_Product_ID /> + <Affiliates_Avangate_Maximum_Commission_Rate /> + <Affiliates_BMTMicro_Order_Page /> + <Affiliates_BMTMicro_Vendor_ID /> + <Affiliates_BMTMicro_Product_ID /> + <Affiliates_BMTMicro_Maximum_Commission_Rate /> + <Affiliates_clixGalore_Order_Page /> + <Affiliates_clixGalore_Vendor_ID /> + <Affiliates_clixGalore_Product_ID /> + <Affiliates_clixGalore_Maximum_Commission_Rate /> + <Affiliates_CommissionJunction_Order_Page /> + <Affiliates_CommissionJunction_Vendor_ID /> + <Affiliates_CommissionJunction_Product_ID /> + <Affiliates_CommissionJunction_Maximum_Commission_Rate /> + <Affiliates_DigiBuy_Order_Page /> + <Affiliates_DigiBuy_Vendor_ID /> + <Affiliates_DigiBuy_Product_ID /> + <Affiliates_DigiBuy_Maximum_Commission_Rate /> + <Affiliates_DigitalCandle_Order_Page /> + <Affiliates_DigitalCandle_Vendor_ID /> + <Affiliates_DigitalCandle_Product_ID /> + <Affiliates_DigitalCandle_Maximum_Commission_Rate /> + <Affiliates_Emetrix_Order_Page /> + <Affiliates_Emetrix_Vendor_ID /> + <Affiliates_Emetrix_Product_ID /> + <Affiliates_Emetrix_Maximum_Commission_Rate /> + <Affiliates_eSellerate_Order_Page /> + <Affiliates_eSellerate_Vendor_ID /> + <Affiliates_eSellerate_Product_ID /> + <Affiliates_eSellerate_Maximum_Commission_Rate /> + <Affiliates_Kagi_Order_Page /> + <Affiliates_Kagi_Vendor_ID /> + <Affiliates_Kagi_Product_ID /> + <Affiliates_Kagi_Maximum_Commission_Rate /> + <Affiliates_LinkShare_Order_Page /> + <Affiliates_LinkShare_Vendor_ID /> + <Affiliates_LinkShare_Product_ID /> + <Affiliates_LinkShare_Maximum_Commission_Rate /> + <Affiliates_NorthStarSol_Order_Page /> + <Affiliates_NorthStarSol_Vendor_ID /> + <Affiliates_NorthStarSol_Product_ID /> + <Affiliates_NorthStarSol_Maximum_Commission_Rate /> + <Affiliates_Order1_Order_Page /> + <Affiliates_Order1_Vendor_ID /> + <Affiliates_Order1_Product_ID /> + <Affiliates_Order1_Maximum_Commission_Rate /> + <Affiliates_Osolis_Order_Page /> + <Affiliates_Osolis_Vendor_ID /> + <Affiliates_Osolis_Product_ID /> + <Affiliates_Osolis_Maximum_Commission_Rate /> + <Affiliates_Plimus_Order_Page /> + <Affiliates_Plimus_Vendor_ID /> + <Affiliates_Plimus_Product_ID /> + <Affiliates_Plimus_Maximum_Commission_Rate /> + <Affiliates_Regnet_Order_Page /> + <Affiliates_Regnet_Vendor_ID /> + <Affiliates_Regnet_Product_ID /> + <Affiliates_Regnet_Maximum_Commission_Rate /> + <Affiliates_Regnow_Order_Page /> + <Affiliates_Regnow_Vendor_ID /> + <Affiliates_Regnow_Product_ID /> + <Affiliates_Regnow_Maximum_Commission_Rate /> + <Affiliates_Regsoft_Order_Page /> + <Affiliates_Regsoft_Vendor_ID /> + <Affiliates_Regsoft_Product_ID /> + <Affiliates_Regsoft_Maximum_Commission_Rate /> + <Affiliates_ShareIt_Order_Page /> + <Affiliates_ShareIt_Vendor_ID /> + <Affiliates_ShareIt_Product_ID /> + <Affiliates_ShareIt_Maximum_Commission_Rate /> + <Affiliates_Shareasale_Order_Page /> + <Affiliates_Shareasale_Vendor_ID /> + <Affiliates_Shareasale_Product_ID /> + <Affiliates_Shareasale_Maximum_Commission_Rate /> + <Affiliates_SWReg_Order_Page /> + <Affiliates_SWReg_Vendor_ID /> + <Affiliates_SWReg_Product_ID /> + <Affiliates_SWReg_Maximum_Commission_Rate /> + <Affiliates_V-Share_Order_Page /> + <Affiliates_V-Share_Vendor_ID /> + <Affiliates_V-Share_Product_ID /> + <Affiliates_V-Share_Maximum_Commission_Rate /> + <Affiliates_VFree_Order_Page /> + <Affiliates_VFree_Vendor_ID /> + <Affiliates_VFree_Product_ID /> + <Affiliates_VFree_Maximum_Commission_Rate /> + <Affiliates_Yaskifo_Order_Page /> + <Affiliates_Yaskifo_Vendor_ID /> + <Affiliates_Yaskifo_Product_ID /> + <Affiliates_Yaskifo_Maximum_Commission_Rate /> + </Affiliates> +</PADGEN_PML> diff --git a/build/pad/Dolibarr v2.1.pml b/build/pad/Dolibarr v2.1.pml index 858bee44e6809fb0d119c4cda2278c29f60c0769..8cbf705d5987534ed240f44dd4c0b7e55bf615c7 100644 --- a/build/pad/Dolibarr v2.1.pml +++ b/build/pad/Dolibarr v2.1.pml @@ -1,178 +1,178 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<PADGEN_PML> - <AppVerInfo>PADGen 3.0.1.35</AppVerInfo> - <CompanyName /> - <Program_Info> - <Program_Name>Dolibarr</Program_Name> - <Program_Version>2.1</Program_Version> - <Program_Release_Month>04</Program_Release_Month> - <Program_Release_Day>27</Program_Release_Day> - <Program_Release_Year>2007</Program_Release_Year> - <Program_Cost_Dollars /> - <Program_Cost_Other_Code /> - <Program_Cost_Other /> - <Program_Type>Freeware</Program_Type> - <Program_Release_Status>Major Update</Program_Release_Status> - <Program_Install_Support>No Install Support</Program_Install_Support> - <Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support> - <Program_Language>English,French</Program_Language> - <Program_Change_Info>http://www.dolibarr.org</Program_Change_Info> - <Program_Specific_Category>Business</Program_Specific_Category> - <Program_Category_Class>Business::Accounting & Finance</Program_Category_Class> - <Program_System_Requirements>None</Program_System_Requirements> - <File_Info> - <File_Size_Bytes>1016660</File_Size_Bytes> - <File_Size_K>992</File_Size_K> - <File_Size_MB>0.97</File_Size_MB> - </File_Info> - <Expire_Info> - <Has_Expire_Info>N</Has_Expire_Info> - <Expire_Count /> - <Expire_Based_On>Days</Expire_Based_On> - <Expire_Other_Info /> - <Expire_Month /> - <Expire_Day /> - <Expire_Year /> - </Expire_Info> - </Program_Info> - <Program_Descriptions> - <English> - <Keywords>dolibarr</Keywords> - <Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45> - <Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80> - <Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250> - <Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450> - <Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000> - </English> - <French> - <Keywords /> - <Char_Desc_45 /> - <Char_Desc_80 /> - <Char_Desc_250 /> - <Char_Desc_450 /> - <Char_Desc_2000 /> - </French> - </Program_Descriptions> - <Web_Info> - <Application_URLs> - <Application_Info_URL>http://www.dolibarr.org</Application_Info_URL> - <Application_Order_URL>http://www.dolibarr.org</Application_Order_URL> - <Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL> - <Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/mylogo.png</Application_Icon_URL> - <Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL> - </Application_URLs> - <Download_URLs> - <Primary_Download_URL>http://www.dolibarr.org/en/files/documents/dolibarr.tgz</Primary_Download_URL> - <Secondary_Download_URL /> - <Additional_Download_URL_1 /> - <Additional_Download_URL_2 /> - </Download_URLs> - </Web_Info> - <Permissions> - <Distribution_Permissions>GNU GPL</Distribution_Permissions> - <EULA>GNU GPL</EULA> - </Permissions> - <ASP> - <ASP_FORM>Y</ASP_FORM> - <ASP_Member>N</ASP_Member> - <ASP_Member_Number /> - </ASP> - <Affiliates> - <Affiliates_FORM>Y</Affiliates_FORM> - <Affiliates_VERSION>1.2</Affiliates_VERSION> - <Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL> - <Affiliates_Information_Page /> - <Affiliates_Avangate_Order_Page /> - <Affiliates_Avangate_Vendor_ID /> - <Affiliates_Avangate_Product_ID /> - <Affiliates_Avangate_Maximum_Commission_Rate /> - <Affiliates_BMTMicro_Order_Page /> - <Affiliates_BMTMicro_Vendor_ID /> - <Affiliates_BMTMicro_Product_ID /> - <Affiliates_BMTMicro_Maximum_Commission_Rate /> - <Affiliates_clixGalore_Order_Page /> - <Affiliates_clixGalore_Vendor_ID /> - <Affiliates_clixGalore_Product_ID /> - <Affiliates_clixGalore_Maximum_Commission_Rate /> - <Affiliates_CommissionJunction_Order_Page /> - <Affiliates_CommissionJunction_Vendor_ID /> - <Affiliates_CommissionJunction_Product_ID /> - <Affiliates_CommissionJunction_Maximum_Commission_Rate /> - <Affiliates_DigiBuy_Order_Page /> - <Affiliates_DigiBuy_Vendor_ID /> - <Affiliates_DigiBuy_Product_ID /> - <Affiliates_DigiBuy_Maximum_Commission_Rate /> - <Affiliates_DigitalCandle_Order_Page /> - <Affiliates_DigitalCandle_Vendor_ID /> - <Affiliates_DigitalCandle_Product_ID /> - <Affiliates_DigitalCandle_Maximum_Commission_Rate /> - <Affiliates_Emetrix_Order_Page /> - <Affiliates_Emetrix_Vendor_ID /> - <Affiliates_Emetrix_Product_ID /> - <Affiliates_Emetrix_Maximum_Commission_Rate /> - <Affiliates_eSellerate_Order_Page /> - <Affiliates_eSellerate_Vendor_ID /> - <Affiliates_eSellerate_Product_ID /> - <Affiliates_eSellerate_Maximum_Commission_Rate /> - <Affiliates_Kagi_Order_Page /> - <Affiliates_Kagi_Vendor_ID /> - <Affiliates_Kagi_Product_ID /> - <Affiliates_Kagi_Maximum_Commission_Rate /> - <Affiliates_LinkShare_Order_Page /> - <Affiliates_LinkShare_Vendor_ID /> - <Affiliates_LinkShare_Product_ID /> - <Affiliates_LinkShare_Maximum_Commission_Rate /> - <Affiliates_NorthStarSol_Order_Page /> - <Affiliates_NorthStarSol_Vendor_ID /> - <Affiliates_NorthStarSol_Product_ID /> - <Affiliates_NorthStarSol_Maximum_Commission_Rate /> - <Affiliates_Order1_Order_Page /> - <Affiliates_Order1_Vendor_ID /> - <Affiliates_Order1_Product_ID /> - <Affiliates_Order1_Maximum_Commission_Rate /> - <Affiliates_Osolis_Order_Page /> - <Affiliates_Osolis_Vendor_ID /> - <Affiliates_Osolis_Product_ID /> - <Affiliates_Osolis_Maximum_Commission_Rate /> - <Affiliates_Plimus_Order_Page /> - <Affiliates_Plimus_Vendor_ID /> - <Affiliates_Plimus_Product_ID /> - <Affiliates_Plimus_Maximum_Commission_Rate /> - <Affiliates_Regnet_Order_Page /> - <Affiliates_Regnet_Vendor_ID /> - <Affiliates_Regnet_Product_ID /> - <Affiliates_Regnet_Maximum_Commission_Rate /> - <Affiliates_Regnow_Order_Page /> - <Affiliates_Regnow_Vendor_ID /> - <Affiliates_Regnow_Product_ID /> - <Affiliates_Regnow_Maximum_Commission_Rate /> - <Affiliates_Regsoft_Order_Page /> - <Affiliates_Regsoft_Vendor_ID /> - <Affiliates_Regsoft_Product_ID /> - <Affiliates_Regsoft_Maximum_Commission_Rate /> - <Affiliates_ShareIt_Order_Page /> - <Affiliates_ShareIt_Vendor_ID /> - <Affiliates_ShareIt_Product_ID /> - <Affiliates_ShareIt_Maximum_Commission_Rate /> - <Affiliates_Shareasale_Order_Page /> - <Affiliates_Shareasale_Vendor_ID /> - <Affiliates_Shareasale_Product_ID /> - <Affiliates_Shareasale_Maximum_Commission_Rate /> - <Affiliates_SWReg_Order_Page /> - <Affiliates_SWReg_Vendor_ID /> - <Affiliates_SWReg_Product_ID /> - <Affiliates_SWReg_Maximum_Commission_Rate /> - <Affiliates_V-Share_Order_Page /> - <Affiliates_V-Share_Vendor_ID /> - <Affiliates_V-Share_Product_ID /> - <Affiliates_V-Share_Maximum_Commission_Rate /> - <Affiliates_VFree_Order_Page /> - <Affiliates_VFree_Vendor_ID /> - <Affiliates_VFree_Product_ID /> - <Affiliates_VFree_Maximum_Commission_Rate /> - <Affiliates_Yaskifo_Order_Page /> - <Affiliates_Yaskifo_Vendor_ID /> - <Affiliates_Yaskifo_Product_ID /> - <Affiliates_Yaskifo_Maximum_Commission_Rate /> - </Affiliates> -</PADGEN_PML> +<?xml version="1.0" encoding="UTF-8" ?> +<PADGEN_PML> + <AppVerInfo>PADGen 3.0.1.35</AppVerInfo> + <CompanyName /> + <Program_Info> + <Program_Name>Dolibarr</Program_Name> + <Program_Version>2.1</Program_Version> + <Program_Release_Month>04</Program_Release_Month> + <Program_Release_Day>27</Program_Release_Day> + <Program_Release_Year>2007</Program_Release_Year> + <Program_Cost_Dollars /> + <Program_Cost_Other_Code /> + <Program_Cost_Other /> + <Program_Type>Freeware</Program_Type> + <Program_Release_Status>Major Update</Program_Release_Status> + <Program_Install_Support>No Install Support</Program_Install_Support> + <Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support> + <Program_Language>English,French</Program_Language> + <Program_Change_Info>http://www.dolibarr.org</Program_Change_Info> + <Program_Specific_Category>Business</Program_Specific_Category> + <Program_Category_Class>Business::Accounting & Finance</Program_Category_Class> + <Program_System_Requirements>None</Program_System_Requirements> + <File_Info> + <File_Size_Bytes>1016660</File_Size_Bytes> + <File_Size_K>992</File_Size_K> + <File_Size_MB>0.97</File_Size_MB> + </File_Info> + <Expire_Info> + <Has_Expire_Info>N</Has_Expire_Info> + <Expire_Count /> + <Expire_Based_On>Days</Expire_Based_On> + <Expire_Other_Info /> + <Expire_Month /> + <Expire_Day /> + <Expire_Year /> + </Expire_Info> + </Program_Info> + <Program_Descriptions> + <English> + <Keywords>dolibarr</Keywords> + <Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45> + <Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80> + <Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250> + <Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450> + <Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000> + </English> + <French> + <Keywords /> + <Char_Desc_45 /> + <Char_Desc_80 /> + <Char_Desc_250 /> + <Char_Desc_450 /> + <Char_Desc_2000 /> + </French> + </Program_Descriptions> + <Web_Info> + <Application_URLs> + <Application_Info_URL>http://www.dolibarr.org</Application_Info_URL> + <Application_Order_URL>http://www.dolibarr.org</Application_Order_URL> + <Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL> + <Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/mylogo.png</Application_Icon_URL> + <Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL> + </Application_URLs> + <Download_URLs> + <Primary_Download_URL>http://www.dolibarr.org/en/files/documents/dolibarr.tgz</Primary_Download_URL> + <Secondary_Download_URL /> + <Additional_Download_URL_1 /> + <Additional_Download_URL_2 /> + </Download_URLs> + </Web_Info> + <Permissions> + <Distribution_Permissions>GNU GPL</Distribution_Permissions> + <EULA>GNU GPL</EULA> + </Permissions> + <ASP> + <ASP_FORM>Y</ASP_FORM> + <ASP_Member>N</ASP_Member> + <ASP_Member_Number /> + </ASP> + <Affiliates> + <Affiliates_FORM>Y</Affiliates_FORM> + <Affiliates_VERSION>1.2</Affiliates_VERSION> + <Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL> + <Affiliates_Information_Page /> + <Affiliates_Avangate_Order_Page /> + <Affiliates_Avangate_Vendor_ID /> + <Affiliates_Avangate_Product_ID /> + <Affiliates_Avangate_Maximum_Commission_Rate /> + <Affiliates_BMTMicro_Order_Page /> + <Affiliates_BMTMicro_Vendor_ID /> + <Affiliates_BMTMicro_Product_ID /> + <Affiliates_BMTMicro_Maximum_Commission_Rate /> + <Affiliates_clixGalore_Order_Page /> + <Affiliates_clixGalore_Vendor_ID /> + <Affiliates_clixGalore_Product_ID /> + <Affiliates_clixGalore_Maximum_Commission_Rate /> + <Affiliates_CommissionJunction_Order_Page /> + <Affiliates_CommissionJunction_Vendor_ID /> + <Affiliates_CommissionJunction_Product_ID /> + <Affiliates_CommissionJunction_Maximum_Commission_Rate /> + <Affiliates_DigiBuy_Order_Page /> + <Affiliates_DigiBuy_Vendor_ID /> + <Affiliates_DigiBuy_Product_ID /> + <Affiliates_DigiBuy_Maximum_Commission_Rate /> + <Affiliates_DigitalCandle_Order_Page /> + <Affiliates_DigitalCandle_Vendor_ID /> + <Affiliates_DigitalCandle_Product_ID /> + <Affiliates_DigitalCandle_Maximum_Commission_Rate /> + <Affiliates_Emetrix_Order_Page /> + <Affiliates_Emetrix_Vendor_ID /> + <Affiliates_Emetrix_Product_ID /> + <Affiliates_Emetrix_Maximum_Commission_Rate /> + <Affiliates_eSellerate_Order_Page /> + <Affiliates_eSellerate_Vendor_ID /> + <Affiliates_eSellerate_Product_ID /> + <Affiliates_eSellerate_Maximum_Commission_Rate /> + <Affiliates_Kagi_Order_Page /> + <Affiliates_Kagi_Vendor_ID /> + <Affiliates_Kagi_Product_ID /> + <Affiliates_Kagi_Maximum_Commission_Rate /> + <Affiliates_LinkShare_Order_Page /> + <Affiliates_LinkShare_Vendor_ID /> + <Affiliates_LinkShare_Product_ID /> + <Affiliates_LinkShare_Maximum_Commission_Rate /> + <Affiliates_NorthStarSol_Order_Page /> + <Affiliates_NorthStarSol_Vendor_ID /> + <Affiliates_NorthStarSol_Product_ID /> + <Affiliates_NorthStarSol_Maximum_Commission_Rate /> + <Affiliates_Order1_Order_Page /> + <Affiliates_Order1_Vendor_ID /> + <Affiliates_Order1_Product_ID /> + <Affiliates_Order1_Maximum_Commission_Rate /> + <Affiliates_Osolis_Order_Page /> + <Affiliates_Osolis_Vendor_ID /> + <Affiliates_Osolis_Product_ID /> + <Affiliates_Osolis_Maximum_Commission_Rate /> + <Affiliates_Plimus_Order_Page /> + <Affiliates_Plimus_Vendor_ID /> + <Affiliates_Plimus_Product_ID /> + <Affiliates_Plimus_Maximum_Commission_Rate /> + <Affiliates_Regnet_Order_Page /> + <Affiliates_Regnet_Vendor_ID /> + <Affiliates_Regnet_Product_ID /> + <Affiliates_Regnet_Maximum_Commission_Rate /> + <Affiliates_Regnow_Order_Page /> + <Affiliates_Regnow_Vendor_ID /> + <Affiliates_Regnow_Product_ID /> + <Affiliates_Regnow_Maximum_Commission_Rate /> + <Affiliates_Regsoft_Order_Page /> + <Affiliates_Regsoft_Vendor_ID /> + <Affiliates_Regsoft_Product_ID /> + <Affiliates_Regsoft_Maximum_Commission_Rate /> + <Affiliates_ShareIt_Order_Page /> + <Affiliates_ShareIt_Vendor_ID /> + <Affiliates_ShareIt_Product_ID /> + <Affiliates_ShareIt_Maximum_Commission_Rate /> + <Affiliates_Shareasale_Order_Page /> + <Affiliates_Shareasale_Vendor_ID /> + <Affiliates_Shareasale_Product_ID /> + <Affiliates_Shareasale_Maximum_Commission_Rate /> + <Affiliates_SWReg_Order_Page /> + <Affiliates_SWReg_Vendor_ID /> + <Affiliates_SWReg_Product_ID /> + <Affiliates_SWReg_Maximum_Commission_Rate /> + <Affiliates_V-Share_Order_Page /> + <Affiliates_V-Share_Vendor_ID /> + <Affiliates_V-Share_Product_ID /> + <Affiliates_V-Share_Maximum_Commission_Rate /> + <Affiliates_VFree_Order_Page /> + <Affiliates_VFree_Vendor_ID /> + <Affiliates_VFree_Product_ID /> + <Affiliates_VFree_Maximum_Commission_Rate /> + <Affiliates_Yaskifo_Order_Page /> + <Affiliates_Yaskifo_Vendor_ID /> + <Affiliates_Yaskifo_Product_ID /> + <Affiliates_Yaskifo_Maximum_Commission_Rate /> + </Affiliates> +</PADGEN_PML> diff --git a/build/pad/pad_dolibarr.htm b/build/pad/pad_dolibarr.htm index 1446ce8dad360b003e37c8618acd80ef0974a82d..6870e758c8ab3d2060a26f53826801a6874e2dd8 100644 Binary files a/build/pad/pad_dolibarr.htm and b/build/pad/pad_dolibarr.htm differ diff --git a/build/pad/pad_dolibarr.xml b/build/pad/pad_dolibarr.xml index 28862b57737e14b15ab871e2e51aec286c6242c8..56a333575447d4df8c41b8d3f9dda76645486ce6 100644 --- a/build/pad/pad_dolibarr.xml +++ b/build/pad/pad_dolibarr.xml @@ -1,208 +1,208 @@ -<?xml version="1.0" ?> -<XML_DIZ_INFO> - <MASTER_PAD_VERSION_INFO> - <MASTER_PAD_VERSION>3.01</MASTER_PAD_VERSION> - <MASTER_PAD_EDITOR>PADGen 3.0.1.35 http://www.padgen.org</MASTER_PAD_EDITOR> - <MASTER_PAD_INFO>Portable Application Description, or PAD for short, is a data set that is used by shareware authors to disseminate information to anyone interested in their software products. To find out more go to http://www.asp-shareware.org/pad</MASTER_PAD_INFO> - </MASTER_PAD_VERSION_INFO> - <Company_Info> - <Company_Name>Laurent Destailleur</Company_Name> - <Address_1>61 Boulevard Vauban</Address_1> - <Address_2 /> - <City_Town>Montigny-le-Bretonneux</City_Town> - <State_Province>Yvelines</State_Province> - <Zip_Postal_Code>78180</Zip_Postal_Code> - <Country>FRANCE</Country> - <Company_WebSite_URL>http://www.destailleur.fr</Company_WebSite_URL> - <Contact_Info> - <Author_First_Name>Laurent</Author_First_Name> - <Author_Last_Name>Destailleur</Author_Last_Name> - <Author_Email>eldy@users.sourceforge.net</Author_Email> - <Contact_First_Name>Laurent</Contact_First_Name> - <Contact_Last_Name>Destailleur</Contact_Last_Name> - <Contact_Email>eldy@users.sourceforge.net</Contact_Email> - </Contact_Info> - <Support_Info> - <Sales_Email>eldy@users.sourceforge.net</Sales_Email> - <Support_Email>eldy@users.sourceforge.net</Support_Email> - <General_Email>eldy@users.sourceforge.net</General_Email> - <Sales_Phone /> - <Support_Phone /> - <General_Phone /> - <Fax_Phone /> - </Support_Info> - </Company_Info> - <Program_Info> - <Program_Name>Dolibarr</Program_Name> - <Program_Version>2.1</Program_Version> - <Program_Release_Month>04</Program_Release_Month> - <Program_Release_Day>27</Program_Release_Day> - <Program_Release_Year>2007</Program_Release_Year> - <Program_Cost_Dollars /> - <Program_Cost_Other_Code /> - <Program_Cost_Other /> - <Program_Type>Freeware</Program_Type> - <Program_Release_Status>Major Update</Program_Release_Status> - <Program_Install_Support>No Install Support</Program_Install_Support> - <Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support> - <Program_Language>English,French</Program_Language> - <Program_Change_Info>http://www.dolibarr.org</Program_Change_Info> - <Program_Specific_Category>Business</Program_Specific_Category> - <Program_Category_Class>Business::Accounting & Finance</Program_Category_Class> - <Program_System_Requirements>None</Program_System_Requirements> - <File_Info> - <File_Size_Bytes>1016660</File_Size_Bytes> - <File_Size_K>992</File_Size_K> - <File_Size_MB>0.97</File_Size_MB> - </File_Info> - <Expire_Info> - <Has_Expire_Info>N</Has_Expire_Info> - <Expire_Count /> - <Expire_Based_On>Days</Expire_Based_On> - <Expire_Other_Info /> - <Expire_Month /> - <Expire_Day /> - <Expire_Year /> - </Expire_Info> - </Program_Info> - <Program_Descriptions> - <English> - <Keywords>dolibarr</Keywords> - <Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45> - <Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80> - <Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250> - <Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450> - <Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000> - </English> - <French> - <Keywords /> - <Char_Desc_45 /> - <Char_Desc_80 /> - <Char_Desc_250 /> - <Char_Desc_450 /> - <Char_Desc_2000 /> - </French> - </Program_Descriptions> - <Web_Info> - <Application_URLs> - <Application_Info_URL>http://www.dolibarr.org</Application_Info_URL> - <Application_Order_URL>http://www.dolibarr.org</Application_Order_URL> - <Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL> - <Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/mylogo.png</Application_Icon_URL> - <Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL> - </Application_URLs> - <Download_URLs> - <Primary_Download_URL>http://www.dolibarr.org/en/files/documents/dolibarr.tgz</Primary_Download_URL> - <Secondary_Download_URL /> - <Additional_Download_URL_1 /> - <Additional_Download_URL_2 /> - </Download_URLs> - </Web_Info> - <Permissions> - <Distribution_Permissions>GNU GPL</Distribution_Permissions> - <EULA>GNU GPL</EULA> - </Permissions> - <ASP> - <ASP_FORM>Y</ASP_FORM> - <ASP_Member>N</ASP_Member> - <ASP_Member_Number /> - </ASP> - <Affiliates> - <Affiliates_FORM>Y</Affiliates_FORM> - <Affiliates_VERSION>1.2</Affiliates_VERSION> - <Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL> - <Affiliates_Information_Page /> - <Affiliates_Avangate_Order_Page /> - <Affiliates_Avangate_Vendor_ID /> - <Affiliates_Avangate_Product_ID /> - <Affiliates_Avangate_Maximum_Commission_Rate /> - <Affiliates_BMTMicro_Order_Page /> - <Affiliates_BMTMicro_Vendor_ID /> - <Affiliates_BMTMicro_Product_ID /> - <Affiliates_BMTMicro_Maximum_Commission_Rate /> - <Affiliates_clixGalore_Order_Page /> - <Affiliates_clixGalore_Vendor_ID /> - <Affiliates_clixGalore_Product_ID /> - <Affiliates_clixGalore_Maximum_Commission_Rate /> - <Affiliates_CommissionJunction_Order_Page /> - <Affiliates_CommissionJunction_Vendor_ID /> - <Affiliates_CommissionJunction_Product_ID /> - <Affiliates_CommissionJunction_Maximum_Commission_Rate /> - <Affiliates_DigiBuy_Order_Page /> - <Affiliates_DigiBuy_Vendor_ID /> - <Affiliates_DigiBuy_Product_ID /> - <Affiliates_DigiBuy_Maximum_Commission_Rate /> - <Affiliates_DigitalCandle_Order_Page /> - <Affiliates_DigitalCandle_Vendor_ID /> - <Affiliates_DigitalCandle_Product_ID /> - <Affiliates_DigitalCandle_Maximum_Commission_Rate /> - <Affiliates_Emetrix_Order_Page /> - <Affiliates_Emetrix_Vendor_ID /> - <Affiliates_Emetrix_Product_ID /> - <Affiliates_Emetrix_Maximum_Commission_Rate /> - <Affiliates_eSellerate_Order_Page /> - <Affiliates_eSellerate_Vendor_ID /> - <Affiliates_eSellerate_Product_ID /> - <Affiliates_eSellerate_Maximum_Commission_Rate /> - <Affiliates_Kagi_Order_Page /> - <Affiliates_Kagi_Vendor_ID /> - <Affiliates_Kagi_Product_ID /> - <Affiliates_Kagi_Maximum_Commission_Rate /> - <Affiliates_LinkShare_Order_Page /> - <Affiliates_LinkShare_Vendor_ID /> - <Affiliates_LinkShare_Product_ID /> - <Affiliates_LinkShare_Maximum_Commission_Rate /> - <Affiliates_NorthStarSol_Order_Page /> - <Affiliates_NorthStarSol_Vendor_ID /> - <Affiliates_NorthStarSol_Product_ID /> - <Affiliates_NorthStarSol_Maximum_Commission_Rate /> - <Affiliates_Order1_Order_Page /> - <Affiliates_Order1_Vendor_ID /> - <Affiliates_Order1_Product_ID /> - <Affiliates_Order1_Maximum_Commission_Rate /> - <Affiliates_Osolis_Order_Page /> - <Affiliates_Osolis_Vendor_ID /> - <Affiliates_Osolis_Product_ID /> - <Affiliates_Osolis_Maximum_Commission_Rate /> - <Affiliates_Plimus_Order_Page /> - <Affiliates_Plimus_Vendor_ID /> - <Affiliates_Plimus_Product_ID /> - <Affiliates_Plimus_Maximum_Commission_Rate /> - <Affiliates_Regnet_Order_Page /> - <Affiliates_Regnet_Vendor_ID /> - <Affiliates_Regnet_Product_ID /> - <Affiliates_Regnet_Maximum_Commission_Rate /> - <Affiliates_Regnow_Order_Page /> - <Affiliates_Regnow_Vendor_ID /> - <Affiliates_Regnow_Product_ID /> - <Affiliates_Regnow_Maximum_Commission_Rate /> - <Affiliates_Regsoft_Order_Page /> - <Affiliates_Regsoft_Vendor_ID /> - <Affiliates_Regsoft_Product_ID /> - <Affiliates_Regsoft_Maximum_Commission_Rate /> - <Affiliates_ShareIt_Order_Page /> - <Affiliates_ShareIt_Vendor_ID /> - <Affiliates_ShareIt_Product_ID /> - <Affiliates_ShareIt_Maximum_Commission_Rate /> - <Affiliates_Shareasale_Order_Page /> - <Affiliates_Shareasale_Vendor_ID /> - <Affiliates_Shareasale_Product_ID /> - <Affiliates_Shareasale_Maximum_Commission_Rate /> - <Affiliates_SWReg_Order_Page /> - <Affiliates_SWReg_Vendor_ID /> - <Affiliates_SWReg_Product_ID /> - <Affiliates_SWReg_Maximum_Commission_Rate /> - <Affiliates_V-Share_Order_Page /> - <Affiliates_V-Share_Vendor_ID /> - <Affiliates_V-Share_Product_ID /> - <Affiliates_V-Share_Maximum_Commission_Rate /> - <Affiliates_VFree_Order_Page /> - <Affiliates_VFree_Vendor_ID /> - <Affiliates_VFree_Product_ID /> - <Affiliates_VFree_Maximum_Commission_Rate /> - <Affiliates_Yaskifo_Order_Page /> - <Affiliates_Yaskifo_Vendor_ID /> - <Affiliates_Yaskifo_Product_ID /> - <Affiliates_Yaskifo_Maximum_Commission_Rate /> - </Affiliates> -</XML_DIZ_INFO> +<?xml version="1.0" ?> +<XML_DIZ_INFO> + <MASTER_PAD_VERSION_INFO> + <MASTER_PAD_VERSION>3.01</MASTER_PAD_VERSION> + <MASTER_PAD_EDITOR>PADGen 3.0.1.35 http://www.padgen.org</MASTER_PAD_EDITOR> + <MASTER_PAD_INFO>Portable Application Description, or PAD for short, is a data set that is used by shareware authors to disseminate information to anyone interested in their software products. To find out more go to http://www.asp-shareware.org/pad</MASTER_PAD_INFO> + </MASTER_PAD_VERSION_INFO> + <Company_Info> + <Company_Name>Laurent Destailleur</Company_Name> + <Address_1>61 Boulevard Vauban</Address_1> + <Address_2 /> + <City_Town>Montigny-le-Bretonneux</City_Town> + <State_Province>Yvelines</State_Province> + <Zip_Postal_Code>78180</Zip_Postal_Code> + <Country>FRANCE</Country> + <Company_WebSite_URL>http://www.destailleur.fr</Company_WebSite_URL> + <Contact_Info> + <Author_First_Name>Laurent</Author_First_Name> + <Author_Last_Name>Destailleur</Author_Last_Name> + <Author_Email>eldy@users.sourceforge.net</Author_Email> + <Contact_First_Name>Laurent</Contact_First_Name> + <Contact_Last_Name>Destailleur</Contact_Last_Name> + <Contact_Email>eldy@users.sourceforge.net</Contact_Email> + </Contact_Info> + <Support_Info> + <Sales_Email>eldy@users.sourceforge.net</Sales_Email> + <Support_Email>eldy@users.sourceforge.net</Support_Email> + <General_Email>eldy@users.sourceforge.net</General_Email> + <Sales_Phone /> + <Support_Phone /> + <General_Phone /> + <Fax_Phone /> + </Support_Info> + </Company_Info> + <Program_Info> + <Program_Name>Dolibarr</Program_Name> + <Program_Version>2.1</Program_Version> + <Program_Release_Month>04</Program_Release_Month> + <Program_Release_Day>27</Program_Release_Day> + <Program_Release_Year>2007</Program_Release_Year> + <Program_Cost_Dollars /> + <Program_Cost_Other_Code /> + <Program_Cost_Other /> + <Program_Type>Freeware</Program_Type> + <Program_Release_Status>Major Update</Program_Release_Status> + <Program_Install_Support>No Install Support</Program_Install_Support> + <Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support> + <Program_Language>English,French</Program_Language> + <Program_Change_Info>http://www.dolibarr.org</Program_Change_Info> + <Program_Specific_Category>Business</Program_Specific_Category> + <Program_Category_Class>Business::Accounting & Finance</Program_Category_Class> + <Program_System_Requirements>None</Program_System_Requirements> + <File_Info> + <File_Size_Bytes>1016660</File_Size_Bytes> + <File_Size_K>992</File_Size_K> + <File_Size_MB>0.97</File_Size_MB> + </File_Info> + <Expire_Info> + <Has_Expire_Info>N</Has_Expire_Info> + <Expire_Count /> + <Expire_Based_On>Days</Expire_Based_On> + <Expire_Other_Info /> + <Expire_Month /> + <Expire_Day /> + <Expire_Year /> + </Expire_Info> + </Program_Info> + <Program_Descriptions> + <English> + <Keywords>dolibarr</Keywords> + <Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45> + <Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80> + <Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250> + <Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450> + <Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000> + </English> + <French> + <Keywords /> + <Char_Desc_45 /> + <Char_Desc_80 /> + <Char_Desc_250 /> + <Char_Desc_450 /> + <Char_Desc_2000 /> + </French> + </Program_Descriptions> + <Web_Info> + <Application_URLs> + <Application_Info_URL>http://www.dolibarr.org</Application_Info_URL> + <Application_Order_URL>http://www.dolibarr.org</Application_Order_URL> + <Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL> + <Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/mylogo.png</Application_Icon_URL> + <Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL> + </Application_URLs> + <Download_URLs> + <Primary_Download_URL>http://www.dolibarr.org/en/files/documents/dolibarr.tgz</Primary_Download_URL> + <Secondary_Download_URL /> + <Additional_Download_URL_1 /> + <Additional_Download_URL_2 /> + </Download_URLs> + </Web_Info> + <Permissions> + <Distribution_Permissions>GNU GPL</Distribution_Permissions> + <EULA>GNU GPL</EULA> + </Permissions> + <ASP> + <ASP_FORM>Y</ASP_FORM> + <ASP_Member>N</ASP_Member> + <ASP_Member_Number /> + </ASP> + <Affiliates> + <Affiliates_FORM>Y</Affiliates_FORM> + <Affiliates_VERSION>1.2</Affiliates_VERSION> + <Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL> + <Affiliates_Information_Page /> + <Affiliates_Avangate_Order_Page /> + <Affiliates_Avangate_Vendor_ID /> + <Affiliates_Avangate_Product_ID /> + <Affiliates_Avangate_Maximum_Commission_Rate /> + <Affiliates_BMTMicro_Order_Page /> + <Affiliates_BMTMicro_Vendor_ID /> + <Affiliates_BMTMicro_Product_ID /> + <Affiliates_BMTMicro_Maximum_Commission_Rate /> + <Affiliates_clixGalore_Order_Page /> + <Affiliates_clixGalore_Vendor_ID /> + <Affiliates_clixGalore_Product_ID /> + <Affiliates_clixGalore_Maximum_Commission_Rate /> + <Affiliates_CommissionJunction_Order_Page /> + <Affiliates_CommissionJunction_Vendor_ID /> + <Affiliates_CommissionJunction_Product_ID /> + <Affiliates_CommissionJunction_Maximum_Commission_Rate /> + <Affiliates_DigiBuy_Order_Page /> + <Affiliates_DigiBuy_Vendor_ID /> + <Affiliates_DigiBuy_Product_ID /> + <Affiliates_DigiBuy_Maximum_Commission_Rate /> + <Affiliates_DigitalCandle_Order_Page /> + <Affiliates_DigitalCandle_Vendor_ID /> + <Affiliates_DigitalCandle_Product_ID /> + <Affiliates_DigitalCandle_Maximum_Commission_Rate /> + <Affiliates_Emetrix_Order_Page /> + <Affiliates_Emetrix_Vendor_ID /> + <Affiliates_Emetrix_Product_ID /> + <Affiliates_Emetrix_Maximum_Commission_Rate /> + <Affiliates_eSellerate_Order_Page /> + <Affiliates_eSellerate_Vendor_ID /> + <Affiliates_eSellerate_Product_ID /> + <Affiliates_eSellerate_Maximum_Commission_Rate /> + <Affiliates_Kagi_Order_Page /> + <Affiliates_Kagi_Vendor_ID /> + <Affiliates_Kagi_Product_ID /> + <Affiliates_Kagi_Maximum_Commission_Rate /> + <Affiliates_LinkShare_Order_Page /> + <Affiliates_LinkShare_Vendor_ID /> + <Affiliates_LinkShare_Product_ID /> + <Affiliates_LinkShare_Maximum_Commission_Rate /> + <Affiliates_NorthStarSol_Order_Page /> + <Affiliates_NorthStarSol_Vendor_ID /> + <Affiliates_NorthStarSol_Product_ID /> + <Affiliates_NorthStarSol_Maximum_Commission_Rate /> + <Affiliates_Order1_Order_Page /> + <Affiliates_Order1_Vendor_ID /> + <Affiliates_Order1_Product_ID /> + <Affiliates_Order1_Maximum_Commission_Rate /> + <Affiliates_Osolis_Order_Page /> + <Affiliates_Osolis_Vendor_ID /> + <Affiliates_Osolis_Product_ID /> + <Affiliates_Osolis_Maximum_Commission_Rate /> + <Affiliates_Plimus_Order_Page /> + <Affiliates_Plimus_Vendor_ID /> + <Affiliates_Plimus_Product_ID /> + <Affiliates_Plimus_Maximum_Commission_Rate /> + <Affiliates_Regnet_Order_Page /> + <Affiliates_Regnet_Vendor_ID /> + <Affiliates_Regnet_Product_ID /> + <Affiliates_Regnet_Maximum_Commission_Rate /> + <Affiliates_Regnow_Order_Page /> + <Affiliates_Regnow_Vendor_ID /> + <Affiliates_Regnow_Product_ID /> + <Affiliates_Regnow_Maximum_Commission_Rate /> + <Affiliates_Regsoft_Order_Page /> + <Affiliates_Regsoft_Vendor_ID /> + <Affiliates_Regsoft_Product_ID /> + <Affiliates_Regsoft_Maximum_Commission_Rate /> + <Affiliates_ShareIt_Order_Page /> + <Affiliates_ShareIt_Vendor_ID /> + <Affiliates_ShareIt_Product_ID /> + <Affiliates_ShareIt_Maximum_Commission_Rate /> + <Affiliates_Shareasale_Order_Page /> + <Affiliates_Shareasale_Vendor_ID /> + <Affiliates_Shareasale_Product_ID /> + <Affiliates_Shareasale_Maximum_Commission_Rate /> + <Affiliates_SWReg_Order_Page /> + <Affiliates_SWReg_Vendor_ID /> + <Affiliates_SWReg_Product_ID /> + <Affiliates_SWReg_Maximum_Commission_Rate /> + <Affiliates_V-Share_Order_Page /> + <Affiliates_V-Share_Vendor_ID /> + <Affiliates_V-Share_Product_ID /> + <Affiliates_V-Share_Maximum_Commission_Rate /> + <Affiliates_VFree_Order_Page /> + <Affiliates_VFree_Vendor_ID /> + <Affiliates_VFree_Product_ID /> + <Affiliates_VFree_Maximum_Commission_Rate /> + <Affiliates_Yaskifo_Order_Page /> + <Affiliates_Yaskifo_Vendor_ID /> + <Affiliates_Yaskifo_Product_ID /> + <Affiliates_Yaskifo_Maximum_Commission_Rate /> + </Affiliates> +</XML_DIZ_INFO> diff --git a/dev/ldap/ldapadd_sample2.txt b/dev/ldap/ldapadd_sample2.txt index c739f1d291a2daa04b95b261ebafe8f72d2a3c6b..356481fe247d03b03fbaf11a40d8e059741a65b9 100644 --- a/dev/ldap/ldapadd_sample2.txt +++ b/dev/ldap/ldapadd_sample2.txt @@ -1,10 +1,10 @@ -# ldapadd_sample2.txt -# -# Use this sample to add a ou "contacts" -# This is the second thing to create after creating the root my-domain -# -# ldapadd -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapadd_sample2.txt - -dn: ou=contacts,dc=my-domain,dc=com -objectClass: organizationalUnit +# ldapadd_sample2.txt +# +# Use this sample to add a ou "contacts" +# This is the second thing to create after creating the root my-domain +# +# ldapadd -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapadd_sample2.txt + +dn: ou=contacts,dc=my-domain,dc=com +objectClass: organizationalUnit ou: contacts \ No newline at end of file diff --git a/doc/wiki/titres_page_wiki.txt b/doc/wiki/titres_page_wiki.txt index ad0563a327f229f209b552dde82df5cc88c52f34..05a3d9398f67b8f9e95ec8cdcc29c34e9e70234c 100644 --- a/doc/wiki/titres_page_wiki.txt +++ b/doc/wiki/titres_page_wiki.txt @@ -1,142 +1,142 @@ -Accueil -Actualit�s -ApercuDesModeles -Authentification -Benoit Mortier -Charte de nommage -Commande -Constantes -Contrat -Customisation des documents dolibarr -Developpement module -Devenir d�veloppeur -DocUtilisateur -DocumentFacture -DocumentPropale -Document g�n�r�s -Documentation D�veloppeur -Documentation d�veloppeur -Documentation traducteur -Documentation utilisateur -Dolibarr -D�pendances -D�veloppement -Export -Compta -FAQUtilisateur -FAQ D�veloppeur -FAQ Langue -FAQ Montants -FAQ Utilisateur -Facturation -Facturation/Comptabilit� -Facture -FactureConfiguration -FactureFournisseur -FactureModele -Fichier de configuration -Glossaire -Imports de masse -Installation -Installation / Mise a jour -Interface OSCommerce -Interfaces Dolibarr vers exterieur -Interfaces Exterieur vers Dolibarr -Langages -Langages et normes -Languages -Laurent Destailleur (Eldy) - Profession de foi -Laurent Destailleur - Profession de foi -Librairies externes -Librairies externes et d�pendances -Liste des tables -Mailing -Main Page -Mise � jour du format de la base -Module Adh�rents -Module Avoir -Module Banque -Module Banque-Caisse -Module Barcode -Module Commandes -Module Comptabilit� -Module Contrat -Module Facture -Module Fournisseur -Module Mailing -Module Propositions commerciales -Module Pr�l�vements bancaires -Module Soci�t� -Module Stock -Module Utilisateurs -Module comptabilit� -Modules -Nomination chef de projet -Normes d�veloppeur -Module Proposition commerciales -Normes d�veloppeur -Module Stock -OpenXtrem -Outils et principes -Permissions -Premiers param�trages -Presse en ligne -Presse papier -Produits -Produits 7.1 -Projet -Projet comptabilit� l�gale -Proposition commerciale -Pr�requis -Roadmap -Roadmap 1.2.0 -Roadmap 1.3.0 -Roadmap 1.4.0 -Roadmap 1.6.0 -Roadmap 2.0.0 -Roadmap 2.1.0 -Roadmap 2.3.0 -Roadmap 2.4.0 -Roadmap 2.6.0 -R�gles de d�veloppement -R�le du chef de projet -Salon Solutions Linux 2005 -Salon Solutions Linux 2006 -Salon Solutions Linux 2007 -Sauvegarder ses_donn�es avant mise � jour -Script facturation-calcul.php -Script facturation-verif.php -Script import-cdr.php -Script mailing-send.php -Script prelevement-verif.php -Services -Soci�t�s -Stocks Librairies externes et d�pendances -Suggestions utilisateurs -Syst�me de menus -Syst�me des boites -Table llx adherent -Table llx action def -Table llx commande -Table llx commandedet -Table llx const -Table llx contrat -Table llx dolibarr modules -Table llx export compta -Table llx facturedet -Table llx paiement -Table llx paiementfourn facturefourn -Table llx prelevement -Table llx prelevement bons -Table llx prelevement facture -Table llx prelevement facture demande -Table llx prelevement lignes -Table llx prelevement rejet -Table llx rights def -Table llx user param -Table llx usergroup -Table llx usergroup rights -Table llx usergroup user -Themes -T�l�phonie -Utiliser ses donn�es pour tester la derni�re version +Accueil +Actualit�s +ApercuDesModeles +Authentification +Benoit Mortier +Charte de nommage +Commande +Constantes +Contrat +Customisation des documents dolibarr +Developpement module +Devenir d�veloppeur +DocUtilisateur +DocumentFacture +DocumentPropale +Document g�n�r�s +Documentation D�veloppeur +Documentation d�veloppeur +Documentation traducteur +Documentation utilisateur +Dolibarr +D�pendances +D�veloppement +Export +Compta +FAQUtilisateur +FAQ D�veloppeur +FAQ Langue +FAQ Montants +FAQ Utilisateur +Facturation +Facturation/Comptabilit� +Facture +FactureConfiguration +FactureFournisseur +FactureModele +Fichier de configuration +Glossaire +Imports de masse +Installation +Installation / Mise a jour +Interface OSCommerce +Interfaces Dolibarr vers exterieur +Interfaces Exterieur vers Dolibarr +Langages +Langages et normes +Languages +Laurent Destailleur (Eldy) - Profession de foi +Laurent Destailleur - Profession de foi +Librairies externes +Librairies externes et d�pendances +Liste des tables +Mailing +Main Page +Mise � jour du format de la base +Module Adh�rents +Module Avoir +Module Banque +Module Banque-Caisse +Module Barcode +Module Commandes +Module Comptabilit� +Module Contrat +Module Facture +Module Fournisseur +Module Mailing +Module Propositions commerciales +Module Pr�l�vements bancaires +Module Soci�t� +Module Stock +Module Utilisateurs +Module comptabilit� +Modules +Nomination chef de projet +Normes d�veloppeur +Module Proposition commerciales +Normes d�veloppeur +Module Stock +OpenXtrem +Outils et principes +Permissions +Premiers param�trages +Presse en ligne +Presse papier +Produits +Produits 7.1 +Projet +Projet comptabilit� l�gale +Proposition commerciale +Pr�requis +Roadmap +Roadmap 1.2.0 +Roadmap 1.3.0 +Roadmap 1.4.0 +Roadmap 1.6.0 +Roadmap 2.0.0 +Roadmap 2.1.0 +Roadmap 2.3.0 +Roadmap 2.4.0 +Roadmap 2.6.0 +R�gles de d�veloppement +R�le du chef de projet +Salon Solutions Linux 2005 +Salon Solutions Linux 2006 +Salon Solutions Linux 2007 +Sauvegarder ses_donn�es avant mise � jour +Script facturation-calcul.php +Script facturation-verif.php +Script import-cdr.php +Script mailing-send.php +Script prelevement-verif.php +Services +Soci�t�s +Stocks Librairies externes et d�pendances +Suggestions utilisateurs +Syst�me de menus +Syst�me des boites +Table llx adherent +Table llx action def +Table llx commande +Table llx commandedet +Table llx const +Table llx contrat +Table llx dolibarr modules +Table llx export compta +Table llx facturedet +Table llx paiement +Table llx paiementfourn facturefourn +Table llx prelevement +Table llx prelevement bons +Table llx prelevement facture +Table llx prelevement facture demande +Table llx prelevement lignes +Table llx prelevement rejet +Table llx rights def +Table llx user param +Table llx usergroup +Table llx usergroup rights +Table llx usergroup user +Themes +T�l�phonie +Utiliser ses donn�es pour tester la derni�re version diff --git a/htdocs/adherents/cartes/carte.php b/htdocs/adherents/cartes/carte.php index 978b693252a6ae81b7009a55179b0fbf972798f8..6316a183db83fa3d72b12688147266f8bf0f77c7 100755 --- a/htdocs/adherents/cartes/carte.php +++ b/htdocs/adherents/cartes/carte.php @@ -1,125 +1,125 @@ -<?php -/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> - * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org> +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org> * Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Id$ - * $Source$ - */ - -/** - \file htdocs/adherents/cartes/carte.php - \ingroup adherent - \brief Page de creation d'une carte PDF - \version $Revision$ -*/ - -require("./pre.inc.php"); -require(DOL_DOCUMENT_ROOT."/adherents/adherent.class.php"); - -require_once('PDF_card.class.php'); - -// liste des patterns remplacable dans le texte a imprimer -$patterns = array ( - '/%PRENOM%/', - '/%NOM%/', - '/%SERVEUR%/', - '/%SOCIETE%/', - '/%ADRESSE%/', - '/%CP%/', - '/%VILLE%/', - '/%PAYS%/', - '/%EMAIL%/', - '/%NAISS%/', - '/%PHOTO%/', - '/%TYPE%/', - '/%ID%/', - '/%ANNEE%/' - ); -/* - *------------------------------------------------- - * Pour cr�er l'objet on a 2 moyens : - * Soit on donne les valeurs en les passant dans un tableau (sert pour un format personnel) - * Soit on donne le type d'�tiquette au format AVERY - *------------------------------------------------- -*/ - -//$pdf = new PDF_Label(array('name'=>'perso1', 'marginLeft'=>1, 'marginTop'=>1, 'NX'=>2, 'NY'=>7, 'SpaceX'=>0, 'SpaceY'=>0, 'width'=>99.1, 'height'=>'38.1', 'metric'=>'mm', 'font-size'=>14), 1, 2); -$pdf = new PDF_card('CARD', 1, 1); - -$pdf->Open(); -$pdf->AddPage(); - -// Choix de l'annee d'impression ou annee courante. -if (!isset($annee)){ - $now = getdate(); - $annee=$now['year']; -} - -// requete en prenant que les adherents a jour de cotisation -$sql = "SELECT d.rowid, d.prenom, d.nom, d.societe, ".$db->pdate("d.datefin")." as datefin,"; -$sql.= " d.adresse, d.cp, d.ville, d.naiss, d.email, d.photo,"; -$sql.= " t.libelle as type,"; -$sql.= " p.libelle as pays"; -$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_pays as p ON d.pays = p.rowid"; -$sql.= " WHERE d.fk_adherent_type = t.rowid AND d.statut = 1 AND datefin >= now()"; -$sql.= " ORDER BY d.rowid ASC"; - -$result = $db->query($sql); -if ($result) -{ - $num = $db->num_rows($result); - $i = 0; - while ($i < $num) - { - $objp = $db->fetch_object($result); - // attribut a remplacer - $replace = array ( - ucfirst(strtolower($objp->prenom)), - strtoupper($objp->nom), - "http://".$_SERVER["SERVER_NAME"]."/", - $objp->societe, - ucwords(strtolower($objp->adresse)), - $objp->cp, - strtoupper($objp->ville), - ucfirst(strtolower($objp->pays)), - $objp->email, - $objp->naiss, - $objp->photo, - $objp->type, - $objp->rowid, - $annee - ); - - // imprime le texte specifique sur la carte - //$pdf->Add_PDF_card(sprintf("%s\n%s\n%s\n%s\n%s, %s\n%s", $objp->type." n� ".$objp->rowid,ucfirst(strtolower($objp->prenom))." ".strtoupper($objp->nom),"<".$objp->email.">", ucwords(strtolower($objp->adresse)), $objp->cp, strtoupper($objp->ville), ucfirst(strtolower($objp->pays))),$annee,"Association FreeLUG http://www.freelug.org/"); - $pdf->Add_PDF_card(preg_replace ($patterns, $replace, ADHERENT_CARD_TEXT),preg_replace ($patterns, $replace, ADHERENT_CARD_HEADER_TEXT),preg_replace ($patterns, $replace, ADHERENT_CARD_FOOTER_TEXT)); - $i++; - } - - $db->close(); - $pdf->Output(); -} -else -{ - dolibarr_print_error($db); - - llxFooter('$Date$ - $Revision$'); -} - -?> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + * $Source$ + */ + +/** + \file htdocs/adherents/cartes/carte.php + \ingroup adherent + \brief Page de creation d'une carte PDF + \version $Revision$ +*/ + +require("./pre.inc.php"); +require(DOL_DOCUMENT_ROOT."/adherents/adherent.class.php"); + +require_once('PDF_card.class.php'); + +// liste des patterns remplacable dans le texte a imprimer +$patterns = array ( + '/%PRENOM%/', + '/%NOM%/', + '/%SERVEUR%/', + '/%SOCIETE%/', + '/%ADRESSE%/', + '/%CP%/', + '/%VILLE%/', + '/%PAYS%/', + '/%EMAIL%/', + '/%NAISS%/', + '/%PHOTO%/', + '/%TYPE%/', + '/%ID%/', + '/%ANNEE%/' + ); +/* + *------------------------------------------------- + * Pour cr�er l'objet on a 2 moyens : + * Soit on donne les valeurs en les passant dans un tableau (sert pour un format personnel) + * Soit on donne le type d'�tiquette au format AVERY + *------------------------------------------------- +*/ + +//$pdf = new PDF_Label(array('name'=>'perso1', 'marginLeft'=>1, 'marginTop'=>1, 'NX'=>2, 'NY'=>7, 'SpaceX'=>0, 'SpaceY'=>0, 'width'=>99.1, 'height'=>'38.1', 'metric'=>'mm', 'font-size'=>14), 1, 2); +$pdf = new PDF_card('CARD', 1, 1); + +$pdf->Open(); +$pdf->AddPage(); + +// Choix de l'annee d'impression ou annee courante. +if (!isset($annee)){ + $now = getdate(); + $annee=$now['year']; +} + +// requete en prenant que les adherents a jour de cotisation +$sql = "SELECT d.rowid, d.prenom, d.nom, d.societe, ".$db->pdate("d.datefin")." as datefin,"; +$sql.= " d.adresse, d.cp, d.ville, d.naiss, d.email, d.photo,"; +$sql.= " t.libelle as type,"; +$sql.= " p.libelle as pays"; +$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_pays as p ON d.pays = p.rowid"; +$sql.= " WHERE d.fk_adherent_type = t.rowid AND d.statut = 1 AND datefin >= now()"; +$sql.= " ORDER BY d.rowid ASC"; + +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $db->fetch_object($result); + // attribut a remplacer + $replace = array ( + ucfirst(strtolower($objp->prenom)), + strtoupper($objp->nom), + "http://".$_SERVER["SERVER_NAME"]."/", + $objp->societe, + ucwords(strtolower($objp->adresse)), + $objp->cp, + strtoupper($objp->ville), + ucfirst(strtolower($objp->pays)), + $objp->email, + $objp->naiss, + $objp->photo, + $objp->type, + $objp->rowid, + $annee + ); + + // imprime le texte specifique sur la carte + //$pdf->Add_PDF_card(sprintf("%s\n%s\n%s\n%s\n%s, %s\n%s", $objp->type." n� ".$objp->rowid,ucfirst(strtolower($objp->prenom))." ".strtoupper($objp->nom),"<".$objp->email.">", ucwords(strtolower($objp->adresse)), $objp->cp, strtoupper($objp->ville), ucfirst(strtolower($objp->pays))),$annee,"Association FreeLUG http://www.freelug.org/"); + $pdf->Add_PDF_card(preg_replace ($patterns, $replace, ADHERENT_CARD_TEXT),preg_replace ($patterns, $replace, ADHERENT_CARD_HEADER_TEXT),preg_replace ($patterns, $replace, ADHERENT_CARD_FOOTER_TEXT)); + $i++; + } + + $db->close(); + $pdf->Output(); +} +else +{ + dolibarr_print_error($db); + + llxFooter('$Date$ - $Revision$'); +} + +?> diff --git a/htdocs/adherents/cartes/etiquette.php b/htdocs/adherents/cartes/etiquette.php index 1ea3e2bb3bae6d477ffc0f1ab810c5e44edffb36..521620e32dffd5019a8749a0f8c6f33f15644f97 100755 --- a/htdocs/adherents/cartes/etiquette.php +++ b/htdocs/adherents/cartes/etiquette.php @@ -1,94 +1,94 @@ -<?php -/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> - * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org> +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org> * Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Id$ - * $Source$ - */ - -/** - \file htdocs/adherents/cartes/etiquette.php - \ingroup adherent - \brief Page de creation d'etiquettes - \version $Revision$ -*/ - -require("./pre.inc.php"); -require(DOL_DOCUMENT_ROOT."/adherents/adherent.class.php"); - -require_once('PDF_card.class.php'); - -/* - *------------------------------------------------- - * Pour cr�er l'objet on a 2 moyens : - * Soit on donne les valeurs en les passant dans un tableau (sert pour un format personnel) - * Soit on donne le type d'�tiquette au format AVERY - *------------------------------------------------- -*/ - -//$pdf = new PDF_Label(array('name'=>'perso1', 'marginLeft'=>1, 'marginTop'=>1, 'NX'=>2, 'NY'=>7, 'SpaceX'=>0, 'SpaceY'=>0, 'width'=>99.1, 'height'=>'38.1', 'metric'=>'mm', 'font-size'=>14), 1, 2); -//$pdf = new PDF_card('CARD', 1, 1); -if (defined("ADHERENT_ETIQUETTE_TYPE") && ADHERENT_ETIQUETTE_TYPE !=''){ - $pdf = new PDF_card(ADHERENT_ETIQUETTE_TYPE, 1, 1); -}else{ - $pdf = new PDF_card('L7163', 1, 1); -} - -$pdf->Open(); -$pdf->AddPage(); - -// Choix de l'annee d'impression ou annee courante. -if (!isset($annee)){ - $now = getdate(); - $annee=$now['year']; -} - -// requete en prenant que les adherents a jour de cotisation -$sql = "SELECT d.rowid, d.prenom, d.nom, d.societe, ".$db->pdate("d.datefin")." as datefin,"; -$sql.= " d.adresse, d.cp, d.ville, d.naiss, d.email, d.photo,"; -$sql.= " t.libelle as type,"; -$sql.= " p.libelle as pays"; -$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_pays as p ON d.pays = p.rowid"; -$sql.= " WHERE d.fk_adherent_type = t.rowid AND d.statut = 1 AND datefin >= now()"; -$sql.= " ORDER BY d.rowid ASC"; - -$result = $db->query($sql); -if ($result) -{ - $num = $db->num_rows(); - $i = 0; - while ($i < $num) - { - $objp = $db->fetch_object($result); - // imprime le texte specifique sur la carte - $pdf->Add_PDF_card(sprintf("%s\n%s\n%s %s\n%s", ucfirst(strtolower($objp->prenom))." ".strtoupper($objp->nom), ucwords(strtolower($objp->adresse)), $objp->cp, strtoupper($objp->ville), ucfirst(strtolower($objp->pays))),'',''); - $i++; - } - - $db->close(); - $pdf->Output(); -} -else -{ - dolibarr_print_error($db); - - llxFooter('$Date$ - $Revision$'); -} - -?> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + * $Source$ + */ + +/** + \file htdocs/adherents/cartes/etiquette.php + \ingroup adherent + \brief Page de creation d'etiquettes + \version $Revision$ +*/ + +require("./pre.inc.php"); +require(DOL_DOCUMENT_ROOT."/adherents/adherent.class.php"); + +require_once('PDF_card.class.php'); + +/* + *------------------------------------------------- + * Pour cr�er l'objet on a 2 moyens : + * Soit on donne les valeurs en les passant dans un tableau (sert pour un format personnel) + * Soit on donne le type d'�tiquette au format AVERY + *------------------------------------------------- +*/ + +//$pdf = new PDF_Label(array('name'=>'perso1', 'marginLeft'=>1, 'marginTop'=>1, 'NX'=>2, 'NY'=>7, 'SpaceX'=>0, 'SpaceY'=>0, 'width'=>99.1, 'height'=>'38.1', 'metric'=>'mm', 'font-size'=>14), 1, 2); +//$pdf = new PDF_card('CARD', 1, 1); +if (defined("ADHERENT_ETIQUETTE_TYPE") && ADHERENT_ETIQUETTE_TYPE !=''){ + $pdf = new PDF_card(ADHERENT_ETIQUETTE_TYPE, 1, 1); +}else{ + $pdf = new PDF_card('L7163', 1, 1); +} + +$pdf->Open(); +$pdf->AddPage(); + +// Choix de l'annee d'impression ou annee courante. +if (!isset($annee)){ + $now = getdate(); + $annee=$now['year']; +} + +// requete en prenant que les adherents a jour de cotisation +$sql = "SELECT d.rowid, d.prenom, d.nom, d.societe, ".$db->pdate("d.datefin")." as datefin,"; +$sql.= " d.adresse, d.cp, d.ville, d.naiss, d.email, d.photo,"; +$sql.= " t.libelle as type,"; +$sql.= " p.libelle as pays"; +$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_pays as p ON d.pays = p.rowid"; +$sql.= " WHERE d.fk_adherent_type = t.rowid AND d.statut = 1 AND datefin >= now()"; +$sql.= " ORDER BY d.rowid ASC"; + +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows(); + $i = 0; + while ($i < $num) + { + $objp = $db->fetch_object($result); + // imprime le texte specifique sur la carte + $pdf->Add_PDF_card(sprintf("%s\n%s\n%s %s\n%s", ucfirst(strtolower($objp->prenom))." ".strtoupper($objp->nom), ucwords(strtolower($objp->adresse)), $objp->cp, strtoupper($objp->ville), ucfirst(strtolower($objp->pays))),'',''); + $i++; + } + + $db->close(); + $pdf->Output(); +} +else +{ + dolibarr_print_error($db); + + llxFooter('$Date$ - $Revision$'); +} + +?> diff --git a/htdocs/admin/menus/images/.cvsignore b/htdocs/admin/menus/images/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/admin/menus/images/.cvsignore +++ b/htdocs/admin/menus/images/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 283e7002f0e2c9889dd2d469f6dad99e0920b9d8..fd3b474c718848ecc85423dd8170c237ecd98e38 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -23,8 +23,8 @@ \file htdocs/admin/tools/dolibarr_export.php \brief Page export de la base \version $Revision$ -*/ - +*/ + require("./pre.inc.php"); include_once $dolibarr_main_document_root."/lib/databases/".$conf->db->type.".lib.php"; @@ -32,556 +32,556 @@ $langs->load("admin"); if (! $user->admin) accessforbidden(); - -$html=new Form($db); - - -/* -* Affichage page -*/ +$html=new Form($db); + + + +/* +* Affichage page +*/ llxHeader(); -print_fiche_titre($langs->trans("Backup"),'','setup'); -print '<br>'; - -print $langs->trans("DatabaseName").' : <b>'.$dolibarr_main_db_name.'</b><br>'; -print '<br>'; - -if ($_GET["msg"]) -{ - print '<div class="error">'.$_GET["msg"].'</div>'; - print '<br>'; - print "\n"; -} - - -print_titre($langs->trans("NewBackup")).'<br>'; - -?> - - - -<!-- Dump of a server --> -<form method="post" action="export.php" name="dump"> - -<input type="hidden" name="export_type" value="server" /> - -<script type="text/javascript" language="javascript"> -//<![CDATA[ -function hide_them_all() { - document.getElementById("mysql_options").style.display = 'none'; -// document.getElementById("csv_options").style.display = 'none'; -// document.getElementById("latex_options").style.display = 'none'; -// document.getElementById("pdf_options").style.display = 'none'; -// document.getElementById("none_options").style.display = 'none'; -} - -function show_checked_option() { - hide_them_all(); - - if (document.getElementById('radio_dump_mysql')) { - document.getElementById('mysql_options').style.display = 'block'; - } -// if (document.getElementById('radio_dump_latex').checked) { -// document.getElementById('latex_options').style.display = 'block'; -// } -// if (document.getElementById('radio_dump_pdf').checked) { -// document.getElementById('pdf_options').style.display = 'block'; -// } -// if (document.getElementById('radio_dump_xml').checked) { -// document.getElementById('none_options').style.display = 'block'; -// } -// if (document.getElementById('radio_dump_csv')) { -// document.getElementById('csv_options').style.display = 'block'; -// } - -} - -//]]> -</script> - -<fieldset id="fieldsetexport"> - - -<!-- LDR --> -<table><tr><td valign="top"> - -<div id="div_container_exportoptions"> -<fieldset id="exportoptions"> -<legend><?php echo $langs->trans("ExportMethod"); ?></legend> - - <div class="formelementrow"> - <input type="radio" name="what" value="mysql" id="radio_dump_mysql" - onclick=" - if (this.checked) { - hide_them_all(); - document.getElementById('mysql_options').style.display = 'block'; - }; return true" - /> - <label for="radio_dump_mysql">MySQLDump</label> - </div> - -<!-- - <div class="formelementrow"> - <input type="radio" name="what" value="latex" id="radio_dump_latex" - onclick=" - if (this.checked) { - hide_them_all(); - document.getElementById('latex_options').style.display = 'block'; - }; return true" - /> - <label for="radio_dump_latex">LaTeX</label> - - </div> - - <div class="formelementrow"> - <input type="radio" name="what" value="pdf" id="radio_dump_pdf" - onclick=" - if (this.checked) { - hide_them_all(); - document.getElementById('pdf_options').style.display = 'block'; - }; return true" - /> - <label for="radio_dump_pdf">PDF</label> - </div> - - <div class="formelementrow"> - <input type="radio" name="what" value="csv" id="radio_dump_csv" - onclick="if - (this.checked) { - hide_them_all(); - document.getElementById('csv_options').style.display = 'block'; - }; return true" - /> - <label for="radio_dump_csv">CSV</label> - </div> - - <div class="formelementrow"> - <input type="radio" name="what" value="xml" id="radio_dump_xml" - onclick=" - if (this.checked) { - hide_them_all(); - document.getElementById('none_options').style.display = 'block'; - }; return true" - /> - <label for="radio_dump_xml">XML</label> - - </div> ---> - -</fieldset> -</div> - -</td><td valign="top"> - - -<div id="div_container_sub_exportoptions"> - - -<fieldset id="mysql_options"> - <legend>Parametres de l'export MySQL</legend> - - <div class="formelementrow"> - Chemin complet de la commande mysqldump:<br /> - <input type="text" name="mysqldump" size="80" - value="<?php echo $conf->global->SYSTEMTOOLS_MYSQLDUMP ?>" /> - </div> - - <div class="formelementrow"> - <input type="checkbox" name="use_transaction" value="yes" - id="checkbox_use_transaction" - /> - <label for="checkbox_use_transaction"> - Utiliser le mode transactionnel</label> - - </div> - - <div class="formelementrow"> - <input type="checkbox" name="disable_fk" value="yes" - id="checkbox_disable_fk" checked="true" - /> - <label for="checkbox_disable_fk"> - Ordre de d�sactivation des cl�s �trang�res � l'import</label> - </div> - <label for="select_sql_compat"> - Compatibilit� de l'exportation:</label> - - <select name="sql_compat" id="select_sql_compat"> - <option value="NONE" selected="selected">NONE</option> -<option value="ANSI">ANSI</option> -<option value="DB2">DB2</option> -<option value="MAXDB">MAXDB</option> -<option value="MYSQL323">MYSQL323</option> -<option value="MYSQL40">MYSQL40</option> -<option value="MSSQL">MSSQL</option> -<option value="ORACLE">ORACLE</option> -<option value="POSTGRESQL">POSTGRESQL</option> - </select> - <fieldset> - <legend>Options d'exportation</legend> - <input type="checkbox" name="drop_database" value="yes" - id="checkbox_drop_database" - /> - <label for="checkbox_drop_database"> - - Ajouter DROP DATABASE</label> - </fieldset> - <fieldset> - <legend> - <input type="checkbox" name="sql_structure" value="structure" - id="checkbox_sql_structure" - checked="checked" onclick=" - if (!this.checked && !document.getElementById('checkbox_sql_data').checked) - return false; - else return true;" /> - <label for="checkbox_sql_structure"> - Structure</label> - </legend> - - <input type="checkbox" name="drop" value="1" id="checkbox_dump_drop" - /> - <label for="checkbox_dump_drop"> - Inclure des �nonc�s "DROP TABLE"</label><br /> - - </fieldset> - <fieldset> - <legend> - - <input type="checkbox" name="sql_data" value="data" - id="checkbox_sql_data" checked="checked" onclick=" - if (!this.checked && (!document.getElementById('checkbox_sql_structure') || !document.getElementById('checkbox_sql_structure').checked)) - return false; - else return true;" /> - <label for="checkbox_sql_data"> - Donn�es</label> - </legend> - <input type="checkbox" name="showcolumns" value="yes" - id="checkbox_dump_showcolumns" - /> - <label for="checkbox_dump_showcolumns"> - Nomme les colonnes</label><br /> - - <input type="checkbox" name="extended_ins" value="yes" - id="checkbox_dump_extended_ins" - /> - <label for="checkbox_dump_extended_ins"> - Insertions �tendues</label><br /> - - <input type="checkbox" name="delayed" value="yes" - id="checkbox_dump_delayed" - /> - - <label for="checkbox_dump_delayed"> - Insertions avec d�lais (DELAYED)</label><br /> - - <input type="checkbox" name="sql_ignore" value="yes" - id="checkbox_dump_ignore" - /> - <label for="checkbox_dump_ignore"> - Ignorer les erreurs de doublons (INSERT IGNORE)</label><br /> - - <input type="checkbox" name="hexforbinary" value="yes" - id="checkbox_hexforbinary" - checked="checked" /> - <label for="checkbox_hexforbinary"> - Encoder les champs binaires en hexad�cimal</label><br /> - - </fieldset> -</fieldset> - -<!-- -<fieldset id="latex_options"> - <legend>Parametres export LaTeX</legend> - - <div class="formelementrow"> - <input type="checkbox" name="latex_caption" value="yes" - id="checkbox_latex_show_caption" - checked="checked" /> - - <label for="checkbox_latex_show_caption"> - Inclure les sous-titres</label> - </div> - - <fieldset> - <legend> - <input type="checkbox" name="latex_structure" value="structure" - id="checkbox_latex_structure" - checked="checked" onclick=" - if (!this.checked && !document.getElementById('checkbox_latex_data').checked) - return false; - else return true;" /> - <label for="checkbox_latex_structure"> - Structure</label> - - </legend> - - <table> - <tr><td><label for="latex_structure_caption"> - Sous-titre de la table</label></td> - <td><input type="text" name="latex_structure_caption" size="30" - value="Structure de la table __TABLE__" - id="latex_structure_caption" /> - </td> - </tr> - <tr><td><label for="latex_structure_continued_caption"> - - Sous-titre de la table (suite)</label></td> - <td><input type="text" name="latex_structure_continued_caption" - value="Structure de la table __TABLE__ (suite)" - size="30" id="latex_structure_continued_caption" /> - </td> - </tr> - <tr><td><label for="latex_structure_label"> - Cl� de l'�tiquette</label></td> - <td><input type="text" name="latex_structure_label" size="30" - value="tab:__TABLE__-structure" - id="latex_structure_label" /> - </td> - - </tr> - </table> - - </fieldset> - <fieldset> - <legend> - <input type="checkbox" name="latex_data" value="data" - id="checkbox_latex_data" - checked="checked" onclick=" - if (!this.checked && (!document.getElementById('checkbox_latex_structure') || !document.getElementById('checkbox_latex_structure').checked)) - return false; - else return true;" /> - <label for="checkbox_latex_data"> - Donn�es</label> - - </legend> - <input type="checkbox" name="latex_showcolumns" value="yes" - id="ch_latex_showcolumns" - checked="checked" /> - <label for="ch_latex_showcolumns"> - Nom des colonnes</label><br /> - <table> - <tr><td><label for="latex_data_caption"> - Sous-titre de la table</label></td> - <td><input type="text" name="latex_data_caption" size="30" - value="Contenu de la table __TABLE__" - id="latex_data_caption" /> - - </td> - </tr> - <tr><td><label for="latex_data_continued_caption"> - Sous-titre de la table (suite)</label></td> - <td><input type="text" name="latex_data_continued_caption" size="30" - value="Contenu de la table __TABLE__ (suite)" - id="latex_data_continued_caption" /> - </td> - </tr> - <tr><td><label for="latex_data_label"> - - Cl� de l'�tiquette</label></td> - <td><input type="text" name="latex_data_label" size="30" - value="tab:__TABLE__-data" - id="latex_data_label" /> - </td> - </tr> - <tr><td><label for="latex_replace_null"> - Remplacer NULL par</label></td> - <td><input type="text" name="latex_replace_null" size="20" - value="\textit{NULL}" - id="latex_replace_null" /> - </td> - - </tr> - </table> - </fieldset> -</fieldset> ---> - -<!-- -<fieldset id="csv_options"> - <input type="hidden" name="csv_data" value="csv_data" /> - <legend>Parametres export CSV</legend> - - <table> - - <tr><td><label for="export_separator"> - Champs termin�s par</label></td> - <td><input type="text" name="export_separator" size="2" - id="export_separator" - value=";" /> - </td> - </tr> - <tr><td><label for="enclosed"> - Champs entour�s par</label></td> - <td><input type="text" name="enclosed" size="2" - id="enclosed" - value=""" /> - - </td> - </tr> - <tr><td><label for="escaped"> - Caract�re sp�cial</label></td> - <td><input type="text" name="escaped" size="2" - id="escaped" - value="\" /> - </td> - </tr> - <tr><td><label for="add_character"> - - Lignes termin�es par</label></td> - <td><input type="text" name="add_character" size="2" - id="add_character" - value="\r\n" /> - </td> - </tr> - <tr><td><label for="csv_replace_null"> - Remplacer NULL par</label></td> - <td><input type="text" name="csv_replace_null" size="20" - id="csv_replace_null" - value="NULL" /> - </td> - - </tr> - </table> - <input type="checkbox" name="showcsvnames" value="yes" - id="checkbox_dump_showcsvnames" - /> - <label for="checkbox_dump_showcsvnames"> - Afficher les noms de champ en premi�re ligne</label> -</fieldset> ---> - -<!-- -<fieldset id="pdf_options"> - <input type="hidden" name="pdf_data" value="pdf_data" /> - - <legend>Parametres export PDF</legend> - - <div class="formelementrow"> - <label for="pdf_report_title">Titre du rapport</label> - <input type="text" name="pdf_report_title" size="50" - value="" - id="pdf_report_title" /> - </div> -</fieldset> ---> - -<!-- -<fieldset id="none_options"> - <legend>Options XML</legend> - Ce format ne comporte pas d'options <input type="hidden" name="xml_data" value="xml_data" /> -</fieldset> ---> - -</div> - - -</td></tr></table> - -<script type="text/javascript" language="javascript"> -//<![CDATA[ - show_checked_option(); - hide_them_all(); -//]]> -</script> - -</fieldset> - - - -<fieldset> - - <label for="filename_template"> - Nom du fichier � g�n�rer</label> : - <input type="text" name="filename_template" size="60" id="filename_template" - value="<?php -$file='mysqldump_'.$dolibarr_main_db_name.'_'.strftime("%Y%m%d%H%M").'.sql'; -echo $file; -?>" /> - -<br><br> - -<?php - -print '<div class="formelementrow">'; -print "\n"; - -print $langs->trans("Compression").': '; - -$compression=array( - 'none' => array('function' => '', 'id' => 'radio_compression_none', 'label' => $langs->trans("None")), -// 'zip' => array('function' => 'zip_open', 'id' => 'radio_compression_zip', 'label' => $langs->trans("Zip")), Not open source - 'gz' => array('function' => 'gz_open', 'id' => 'radio_compression_gzip', 'label' => $langs->trans("Gzip")), - 'bz' => array('function' => 'bz_open', 'id' => 'radio_compression_bzip', 'label' => $langs->trans("Bzip2")) -); - -foreach($compression as $key => $val) -{ - if (! $val['function'] || function_exists($val['function'])) - { - print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'"'; - print ' onclick="document.getElementById(\'checkbox_dump_asfile\').checked = true;" checked="checked" />'; - print ' <label for="radio_compression_none">'.$val['label'].'</label>'; - } - else - { - print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" disabled="true">'; - print ' <label for="radio_compression_none">'.$val['label'].'</label>'; - print ' ('.$langs->trans("NotAvailable").')'; - } - print ' '; -} - -print '</div>'; -print "\n"; - -?> - -</fieldset> - - -<center> - <input type="submit" class="button" value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br><br> -</center> - - -</form> - - -<script type="text/javascript" language="javascript"> -//<![CDATA[ - - -// set current db, table and sql query in the querywindow -if (window.parent.refreshLeft) { - window.parent.reload_querywindow("","",""); -} - - -if (window.parent.frames[1]) { - // reset content frame name, as querywindow needs to set a unique name - // before submitting form data, and navigation frame needs the original name - if (window.parent.frames[1].name != 'frame_content') { - window.parent.frames[1].name = 'frame_content'; - } - if (window.parent.frames[1].id != 'frame_content') { - window.parent.frames[1].id = 'frame_content'; - } - //window.parent.frames[1].setAttribute('name', 'frame_content'); - //window.parent.frames[1].setAttribute('id', 'frame_content'); -} -//]]> -</script> - - -<?php - - +print_fiche_titre($langs->trans("Backup"),'','setup'); +print '<br>'; + +print $langs->trans("DatabaseName").' : <b>'.$dolibarr_main_db_name.'</b><br>'; +print '<br>'; + +if ($_GET["msg"]) +{ + print '<div class="error">'.$_GET["msg"].'</div>'; + print '<br>'; + print "\n"; +} + + +print_titre($langs->trans("NewBackup")).'<br>'; + +?> + + + +<!-- Dump of a server --> +<form method="post" action="export.php" name="dump"> + +<input type="hidden" name="export_type" value="server" /> + +<script type="text/javascript" language="javascript"> +//<![CDATA[ +function hide_them_all() { + document.getElementById("mysql_options").style.display = 'none'; +// document.getElementById("csv_options").style.display = 'none'; +// document.getElementById("latex_options").style.display = 'none'; +// document.getElementById("pdf_options").style.display = 'none'; +// document.getElementById("none_options").style.display = 'none'; +} + +function show_checked_option() { + hide_them_all(); + + if (document.getElementById('radio_dump_mysql')) { + document.getElementById('mysql_options').style.display = 'block'; + } +// if (document.getElementById('radio_dump_latex').checked) { +// document.getElementById('latex_options').style.display = 'block'; +// } +// if (document.getElementById('radio_dump_pdf').checked) { +// document.getElementById('pdf_options').style.display = 'block'; +// } +// if (document.getElementById('radio_dump_xml').checked) { +// document.getElementById('none_options').style.display = 'block'; +// } +// if (document.getElementById('radio_dump_csv')) { +// document.getElementById('csv_options').style.display = 'block'; +// } + +} + +//]]> +</script> + +<fieldset id="fieldsetexport"> + + +<!-- LDR --> +<table><tr><td valign="top"> + +<div id="div_container_exportoptions"> +<fieldset id="exportoptions"> +<legend><?php echo $langs->trans("ExportMethod"); ?></legend> + + <div class="formelementrow"> + <input type="radio" name="what" value="mysql" id="radio_dump_mysql" + onclick=" + if (this.checked) { + hide_them_all(); + document.getElementById('mysql_options').style.display = 'block'; + }; return true" + /> + <label for="radio_dump_mysql">MySQLDump</label> + </div> + +<!-- + <div class="formelementrow"> + <input type="radio" name="what" value="latex" id="radio_dump_latex" + onclick=" + if (this.checked) { + hide_them_all(); + document.getElementById('latex_options').style.display = 'block'; + }; return true" + /> + <label for="radio_dump_latex">LaTeX</label> + + </div> + + <div class="formelementrow"> + <input type="radio" name="what" value="pdf" id="radio_dump_pdf" + onclick=" + if (this.checked) { + hide_them_all(); + document.getElementById('pdf_options').style.display = 'block'; + }; return true" + /> + <label for="radio_dump_pdf">PDF</label> + </div> + + <div class="formelementrow"> + <input type="radio" name="what" value="csv" id="radio_dump_csv" + onclick="if + (this.checked) { + hide_them_all(); + document.getElementById('csv_options').style.display = 'block'; + }; return true" + /> + <label for="radio_dump_csv">CSV</label> + </div> + + <div class="formelementrow"> + <input type="radio" name="what" value="xml" id="radio_dump_xml" + onclick=" + if (this.checked) { + hide_them_all(); + document.getElementById('none_options').style.display = 'block'; + }; return true" + /> + <label for="radio_dump_xml">XML</label> + + </div> +--> + +</fieldset> +</div> + +</td><td valign="top"> + + +<div id="div_container_sub_exportoptions"> + + +<fieldset id="mysql_options"> + <legend>Parametres de l'export MySQL</legend> + + <div class="formelementrow"> + Chemin complet de la commande mysqldump:<br /> + <input type="text" name="mysqldump" size="80" + value="<?php echo $conf->global->SYSTEMTOOLS_MYSQLDUMP ?>" /> + </div> + + <div class="formelementrow"> + <input type="checkbox" name="use_transaction" value="yes" + id="checkbox_use_transaction" + /> + <label for="checkbox_use_transaction"> + Utiliser le mode transactionnel</label> + + </div> + + <div class="formelementrow"> + <input type="checkbox" name="disable_fk" value="yes" + id="checkbox_disable_fk" checked="true" + /> + <label for="checkbox_disable_fk"> + Ordre de d�sactivation des cl�s �trang�res � l'import</label> + </div> + <label for="select_sql_compat"> + Compatibilit� de l'exportation:</label> + + <select name="sql_compat" id="select_sql_compat"> + <option value="NONE" selected="selected">NONE</option> +<option value="ANSI">ANSI</option> +<option value="DB2">DB2</option> +<option value="MAXDB">MAXDB</option> +<option value="MYSQL323">MYSQL323</option> +<option value="MYSQL40">MYSQL40</option> +<option value="MSSQL">MSSQL</option> +<option value="ORACLE">ORACLE</option> +<option value="POSTGRESQL">POSTGRESQL</option> + </select> + <fieldset> + <legend>Options d'exportation</legend> + <input type="checkbox" name="drop_database" value="yes" + id="checkbox_drop_database" + /> + <label for="checkbox_drop_database"> + + Ajouter DROP DATABASE</label> + </fieldset> + <fieldset> + <legend> + <input type="checkbox" name="sql_structure" value="structure" + id="checkbox_sql_structure" + checked="checked" onclick=" + if (!this.checked && !document.getElementById('checkbox_sql_data').checked) + return false; + else return true;" /> + <label for="checkbox_sql_structure"> + Structure</label> + </legend> + + <input type="checkbox" name="drop" value="1" id="checkbox_dump_drop" + /> + <label for="checkbox_dump_drop"> + Inclure des �nonc�s "DROP TABLE"</label><br /> + + </fieldset> + <fieldset> + <legend> + + <input type="checkbox" name="sql_data" value="data" + id="checkbox_sql_data" checked="checked" onclick=" + if (!this.checked && (!document.getElementById('checkbox_sql_structure') || !document.getElementById('checkbox_sql_structure').checked)) + return false; + else return true;" /> + <label for="checkbox_sql_data"> + Donn�es</label> + </legend> + <input type="checkbox" name="showcolumns" value="yes" + id="checkbox_dump_showcolumns" + /> + <label for="checkbox_dump_showcolumns"> + Nomme les colonnes</label><br /> + + <input type="checkbox" name="extended_ins" value="yes" + id="checkbox_dump_extended_ins" + /> + <label for="checkbox_dump_extended_ins"> + Insertions �tendues</label><br /> + + <input type="checkbox" name="delayed" value="yes" + id="checkbox_dump_delayed" + /> + + <label for="checkbox_dump_delayed"> + Insertions avec d�lais (DELAYED)</label><br /> + + <input type="checkbox" name="sql_ignore" value="yes" + id="checkbox_dump_ignore" + /> + <label for="checkbox_dump_ignore"> + Ignorer les erreurs de doublons (INSERT IGNORE)</label><br /> + + <input type="checkbox" name="hexforbinary" value="yes" + id="checkbox_hexforbinary" + checked="checked" /> + <label for="checkbox_hexforbinary"> + Encoder les champs binaires en hexad�cimal</label><br /> + + </fieldset> +</fieldset> + +<!-- +<fieldset id="latex_options"> + <legend>Parametres export LaTeX</legend> + + <div class="formelementrow"> + <input type="checkbox" name="latex_caption" value="yes" + id="checkbox_latex_show_caption" + checked="checked" /> + + <label for="checkbox_latex_show_caption"> + Inclure les sous-titres</label> + </div> + + <fieldset> + <legend> + <input type="checkbox" name="latex_structure" value="structure" + id="checkbox_latex_structure" + checked="checked" onclick=" + if (!this.checked && !document.getElementById('checkbox_latex_data').checked) + return false; + else return true;" /> + <label for="checkbox_latex_structure"> + Structure</label> + + </legend> + + <table> + <tr><td><label for="latex_structure_caption"> + Sous-titre de la table</label></td> + <td><input type="text" name="latex_structure_caption" size="30" + value="Structure de la table __TABLE__" + id="latex_structure_caption" /> + </td> + </tr> + <tr><td><label for="latex_structure_continued_caption"> + + Sous-titre de la table (suite)</label></td> + <td><input type="text" name="latex_structure_continued_caption" + value="Structure de la table __TABLE__ (suite)" + size="30" id="latex_structure_continued_caption" /> + </td> + </tr> + <tr><td><label for="latex_structure_label"> + Cl� de l'�tiquette</label></td> + <td><input type="text" name="latex_structure_label" size="30" + value="tab:__TABLE__-structure" + id="latex_structure_label" /> + </td> + + </tr> + </table> + + </fieldset> + <fieldset> + <legend> + <input type="checkbox" name="latex_data" value="data" + id="checkbox_latex_data" + checked="checked" onclick=" + if (!this.checked && (!document.getElementById('checkbox_latex_structure') || !document.getElementById('checkbox_latex_structure').checked)) + return false; + else return true;" /> + <label for="checkbox_latex_data"> + Donn�es</label> + + </legend> + <input type="checkbox" name="latex_showcolumns" value="yes" + id="ch_latex_showcolumns" + checked="checked" /> + <label for="ch_latex_showcolumns"> + Nom des colonnes</label><br /> + <table> + <tr><td><label for="latex_data_caption"> + Sous-titre de la table</label></td> + <td><input type="text" name="latex_data_caption" size="30" + value="Contenu de la table __TABLE__" + id="latex_data_caption" /> + + </td> + </tr> + <tr><td><label for="latex_data_continued_caption"> + Sous-titre de la table (suite)</label></td> + <td><input type="text" name="latex_data_continued_caption" size="30" + value="Contenu de la table __TABLE__ (suite)" + id="latex_data_continued_caption" /> + </td> + </tr> + <tr><td><label for="latex_data_label"> + + Cl� de l'�tiquette</label></td> + <td><input type="text" name="latex_data_label" size="30" + value="tab:__TABLE__-data" + id="latex_data_label" /> + </td> + </tr> + <tr><td><label for="latex_replace_null"> + Remplacer NULL par</label></td> + <td><input type="text" name="latex_replace_null" size="20" + value="\textit{NULL}" + id="latex_replace_null" /> + </td> + + </tr> + </table> + </fieldset> +</fieldset> +--> + +<!-- +<fieldset id="csv_options"> + <input type="hidden" name="csv_data" value="csv_data" /> + <legend>Parametres export CSV</legend> + + <table> + + <tr><td><label for="export_separator"> + Champs termin�s par</label></td> + <td><input type="text" name="export_separator" size="2" + id="export_separator" + value=";" /> + </td> + </tr> + <tr><td><label for="enclosed"> + Champs entour�s par</label></td> + <td><input type="text" name="enclosed" size="2" + id="enclosed" + value=""" /> + + </td> + </tr> + <tr><td><label for="escaped"> + Caract�re sp�cial</label></td> + <td><input type="text" name="escaped" size="2" + id="escaped" + value="\" /> + </td> + </tr> + <tr><td><label for="add_character"> + + Lignes termin�es par</label></td> + <td><input type="text" name="add_character" size="2" + id="add_character" + value="\r\n" /> + </td> + </tr> + <tr><td><label for="csv_replace_null"> + Remplacer NULL par</label></td> + <td><input type="text" name="csv_replace_null" size="20" + id="csv_replace_null" + value="NULL" /> + </td> + + </tr> + </table> + <input type="checkbox" name="showcsvnames" value="yes" + id="checkbox_dump_showcsvnames" + /> + <label for="checkbox_dump_showcsvnames"> + Afficher les noms de champ en premi�re ligne</label> +</fieldset> +--> + +<!-- +<fieldset id="pdf_options"> + <input type="hidden" name="pdf_data" value="pdf_data" /> + + <legend>Parametres export PDF</legend> + + <div class="formelementrow"> + <label for="pdf_report_title">Titre du rapport</label> + <input type="text" name="pdf_report_title" size="50" + value="" + id="pdf_report_title" /> + </div> +</fieldset> +--> + +<!-- +<fieldset id="none_options"> + <legend>Options XML</legend> + Ce format ne comporte pas d'options <input type="hidden" name="xml_data" value="xml_data" /> +</fieldset> +--> + +</div> + + +</td></tr></table> + +<script type="text/javascript" language="javascript"> +//<![CDATA[ + show_checked_option(); + hide_them_all(); +//]]> +</script> + +</fieldset> + + + +<fieldset> + + <label for="filename_template"> + Nom du fichier � g�n�rer</label> : + <input type="text" name="filename_template" size="60" id="filename_template" + value="<?php +$file='mysqldump_'.$dolibarr_main_db_name.'_'.strftime("%Y%m%d%H%M").'.sql'; +echo $file; +?>" /> + +<br><br> + +<?php + +print '<div class="formelementrow">'; +print "\n"; + +print $langs->trans("Compression").': '; + +$compression=array( + 'none' => array('function' => '', 'id' => 'radio_compression_none', 'label' => $langs->trans("None")), +// 'zip' => array('function' => 'zip_open', 'id' => 'radio_compression_zip', 'label' => $langs->trans("Zip")), Not open source + 'gz' => array('function' => 'gz_open', 'id' => 'radio_compression_gzip', 'label' => $langs->trans("Gzip")), + 'bz' => array('function' => 'bz_open', 'id' => 'radio_compression_bzip', 'label' => $langs->trans("Bzip2")) +); + +foreach($compression as $key => $val) +{ + if (! $val['function'] || function_exists($val['function'])) + { + print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'"'; + print ' onclick="document.getElementById(\'checkbox_dump_asfile\').checked = true;" checked="checked" />'; + print ' <label for="radio_compression_none">'.$val['label'].'</label>'; + } + else + { + print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" disabled="true">'; + print ' <label for="radio_compression_none">'.$val['label'].'</label>'; + print ' ('.$langs->trans("NotAvailable").')'; + } + print ' '; +} + +print '</div>'; +print "\n"; + +?> + +</fieldset> + + +<center> + <input type="submit" class="button" value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br><br> +</center> + + +</form> + + +<script type="text/javascript" language="javascript"> +//<![CDATA[ + + +// set current db, table and sql query in the querywindow +if (window.parent.refreshLeft) { + window.parent.reload_querywindow("","",""); +} + + +if (window.parent.frames[1]) { + // reset content frame name, as querywindow needs to set a unique name + // before submitting form data, and navigation frame needs the original name + if (window.parent.frames[1].name != 'frame_content') { + window.parent.frames[1].name = 'frame_content'; + } + if (window.parent.frames[1].id != 'frame_content') { + window.parent.frames[1].id = 'frame_content'; + } + //window.parent.frames[1].setAttribute('name', 'frame_content'); + //window.parent.frames[1].setAttribute('id', 'frame_content'); +} +//]]> +</script> + + +<?php + + $result=$html->show_documents('systemtools','',DOL_DATA_ROOT.'/admin/temp',$_SERVER['PHP_SELF'],0,1); -//if ($result) print '<br><br>'; - - - +//if ($result) print '<br><br>'; + + + llxFooter('$Date$ - $Revision$'); ?> \ No newline at end of file diff --git a/htdocs/conf/.cvsignore b/htdocs/conf/.cvsignore index d31e2af3e1ba4735af5ee13ddfbeff16b0b86fd4..a881a5c0c25ea11db58fa66abc6c433e8150f0e0 100644 --- a/htdocs/conf/.cvsignore +++ b/htdocs/conf/.cvsignore @@ -1,2 +1,2 @@ -conf.php*.sav -*.php +conf.php*.sav +*.php diff --git a/htdocs/includes/.cvsignore b/htdocs/includes/.cvsignore index b35bb5ec87764f0b701a16c514dd04c47cdf375f..ca83ad36d654fbe3c4f0de6f1c131a0c59f93908 100644 --- a/htdocs/includes/.cvsignore +++ b/htdocs/includes/.cvsignore @@ -1 +1 @@ -jpgraph2 +jpgraph2 diff --git a/htdocs/includes/fckeditor/editor/filemanager/browser/default/connectors/test.html b/htdocs/includes/fckeditor/editor/filemanager/browser/default/connectors/test.html index 624be6cc14545bb5b494f7e1d29c9da751afd816..51dbb5f148a1d07aee2865acce90c342a073acdc 100644 --- a/htdocs/includes/fckeditor/editor/filemanager/browser/default/connectors/test.html +++ b/htdocs/includes/fckeditor/editor/filemanager/browser/default/connectors/test.html @@ -1,177 +1,177 @@ -<!-- - * FCKeditor - The text editor for internet - * Copyright (C) 2003-2006 Frederico Caldeira Knabben - * - * Licensed under the terms of the GNU Lesser General Public License: - * http://www.opensource.org/licenses/lgpl-license.php - * - * For further information visit: - * http://www.fckeditor.net/ - * - * "Support Open Source software. What about a donation today?" - * - * File Name: test.html - * Test page for the File Browser connectors. - * - * File Authors: - * Frederico Caldeira Knabben (fredck@fckeditor.net) ---> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <title>FCKeditor - Connectors Tests</title> - <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" /> - <script type="text/javascript"> - -function BuildBaseUrl( command ) -{ - var sUrl = - document.getElementById('cmbConnector').value + - '?Command=' + command + - '&Type=' + document.getElementById('cmbType').value + - '&CurrentFolder=' + document.getElementById('txtFolder').value ; - - return sUrl ; -} - -function SetFrameUrl( url ) -{ - if ( document.all ) - eRunningFrame.document.location = url ; - else - document.getElementById('eRunningFrame').src = url ; - - document.getElementById('eUrl').innerHTML = url ; -} - -function GetFolders() -{ - SetFrameUrl( BuildBaseUrl( 'GetFolders' ) ) ; - return false ; -} - -function GetFoldersAndFiles() -{ - SetFrameUrl( BuildBaseUrl( 'GetFoldersAndFiles' ) ) ; - return false ; -} - -function CreateFolder() -{ - var sFolder = prompt( 'Type the folder name:', 'Test Folder' ) ; - - if ( ! sFolder ) - return ; - - var sUrl = BuildBaseUrl( 'CreateFolder' ) ; - sUrl += '&NewFolderName=' + escape( sFolder ) ; - - SetFrameUrl( sUrl ) ; - return false ; -} - -function OnUploadCompleted( errorNumber, fileName ) -{ - switch ( errorNumber ) - { - case 0 : - alert( 'File uploaded with no errors' ) ; - break ; - case 201 : - GetFoldersAndFiles() - alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ; - break ; - case 202 : - alert( 'Invalid file' ) ; - break ; - default : - alert( 'Error on file upload. Error number: ' + errorNumber ) ; - break ; - } -} - -this.frames.frmUpload = this ; - -function SetAction() -{ - var sUrl = BuildBaseUrl( 'FileUpload' ) ; - document.getElementById('eUrl').innerHTML = sUrl ; - document.getElementById('frmUpload').action = sUrl ; -} - - </script> -</head> -<body> - <table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0"> - <tr> - <td> - <table cellspacing="0" cellpadding="0" border="0"> - <tr> - <td> - Connector:<br /> - <select id="cmbConnector" name="cmbConnector"> - <option value="asp/connector.asp" selected="selected">ASP</option> - <option value="aspx/connector.aspx">ASP.Net</option> - <option value="cfm/connector.cfm">ColdFusion</option> - <option value="lasso/connector.lasso">Lasso</option> - <option value="perl/connector.cgi">Perl</option> - <option value="php/connector.php">PHP</option> - <option value="py/connector.py">Python</option> - </select> - </td> - <td> - </td> - <td> - Current Folder<br /> - <input id="txtFolder" type="text" value="/" name="txtFolder" /></td> - <td> - </td> - <td> - Resource Type<br /> - <select id="cmbType" name="cmbType"> - <option value="File" selected="selected">File</option> - <option value="Image">Image</option> - <option value="Flash">Flash</option> - <option value="Media">Media</option> - <option value="Invalid">Invalid Type (for testing)</option> - </select> - </td> - </tr> - </table> - <br /> - <table cellspacing="0" cellpadding="0" border="0"> - <tr> - <td valign="top"> - <a href="#" onclick="GetFolders();">Get Folders</a></td> - <td> - </td> - <td valign="top"> - <a href="#" onclick="GetFoldersAndFiles();">Get Folders and Files</a></td> - <td> - </td> - <td valign="top"> - <a href="#" onclick="CreateFolder();">Create Folder</a></td> - <td> - </td> - <td valign="top"> - <form id="frmUpload" action="" target="eRunningFrame" method="post" enctype="multipart/form-data"> - File Upload<br /> - <input id="txtFileUpload" type="file" name="NewFile" /> - <input type="submit" value="Upload" onclick="SetAction();" /> - </form> - </td> - </tr> - </table> - <br /> - URL: <span id="eUrl"></span> - </td> - </tr> - <tr> - <td height="100%" valign="top"> - <iframe id="eRunningFrame" src="../../../../fckblank.html" name="eRunningFrame" width="100%" - height="100%"></iframe> - </td> - </tr> - </table> -</body> -</html> +<!-- + * FCKeditor - The text editor for internet + * Copyright (C) 2003-2006 Frederico Caldeira Knabben + * + * Licensed under the terms of the GNU Lesser General Public License: + * http://www.opensource.org/licenses/lgpl-license.php + * + * For further information visit: + * http://www.fckeditor.net/ + * + * "Support Open Source software. What about a donation today?" + * + * File Name: test.html + * Test page for the File Browser connectors. + * + * File Authors: + * Frederico Caldeira Knabben (fredck@fckeditor.net) +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>FCKeditor - Connectors Tests</title> + <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" /> + <script type="text/javascript"> + +function BuildBaseUrl( command ) +{ + var sUrl = + document.getElementById('cmbConnector').value + + '?Command=' + command + + '&Type=' + document.getElementById('cmbType').value + + '&CurrentFolder=' + document.getElementById('txtFolder').value ; + + return sUrl ; +} + +function SetFrameUrl( url ) +{ + if ( document.all ) + eRunningFrame.document.location = url ; + else + document.getElementById('eRunningFrame').src = url ; + + document.getElementById('eUrl').innerHTML = url ; +} + +function GetFolders() +{ + SetFrameUrl( BuildBaseUrl( 'GetFolders' ) ) ; + return false ; +} + +function GetFoldersAndFiles() +{ + SetFrameUrl( BuildBaseUrl( 'GetFoldersAndFiles' ) ) ; + return false ; +} + +function CreateFolder() +{ + var sFolder = prompt( 'Type the folder name:', 'Test Folder' ) ; + + if ( ! sFolder ) + return ; + + var sUrl = BuildBaseUrl( 'CreateFolder' ) ; + sUrl += '&NewFolderName=' + escape( sFolder ) ; + + SetFrameUrl( sUrl ) ; + return false ; +} + +function OnUploadCompleted( errorNumber, fileName ) +{ + switch ( errorNumber ) + { + case 0 : + alert( 'File uploaded with no errors' ) ; + break ; + case 201 : + GetFoldersAndFiles() + alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ; + break ; + case 202 : + alert( 'Invalid file' ) ; + break ; + default : + alert( 'Error on file upload. Error number: ' + errorNumber ) ; + break ; + } +} + +this.frames.frmUpload = this ; + +function SetAction() +{ + var sUrl = BuildBaseUrl( 'FileUpload' ) ; + document.getElementById('eUrl').innerHTML = sUrl ; + document.getElementById('frmUpload').action = sUrl ; +} + + </script> +</head> +<body> + <table height="100%" cellspacing="0" cellpadding="0" width="100%" border="0"> + <tr> + <td> + <table cellspacing="0" cellpadding="0" border="0"> + <tr> + <td> + Connector:<br /> + <select id="cmbConnector" name="cmbConnector"> + <option value="asp/connector.asp" selected="selected">ASP</option> + <option value="aspx/connector.aspx">ASP.Net</option> + <option value="cfm/connector.cfm">ColdFusion</option> + <option value="lasso/connector.lasso">Lasso</option> + <option value="perl/connector.cgi">Perl</option> + <option value="php/connector.php">PHP</option> + <option value="py/connector.py">Python</option> + </select> + </td> + <td> + </td> + <td> + Current Folder<br /> + <input id="txtFolder" type="text" value="/" name="txtFolder" /></td> + <td> + </td> + <td> + Resource Type<br /> + <select id="cmbType" name="cmbType"> + <option value="File" selected="selected">File</option> + <option value="Image">Image</option> + <option value="Flash">Flash</option> + <option value="Media">Media</option> + <option value="Invalid">Invalid Type (for testing)</option> + </select> + </td> + </tr> + </table> + <br /> + <table cellspacing="0" cellpadding="0" border="0"> + <tr> + <td valign="top"> + <a href="#" onclick="GetFolders();">Get Folders</a></td> + <td> + </td> + <td valign="top"> + <a href="#" onclick="GetFoldersAndFiles();">Get Folders and Files</a></td> + <td> + </td> + <td valign="top"> + <a href="#" onclick="CreateFolder();">Create Folder</a></td> + <td> + </td> + <td valign="top"> + <form id="frmUpload" action="" target="eRunningFrame" method="post" enctype="multipart/form-data"> + File Upload<br /> + <input id="txtFileUpload" type="file" name="NewFile" /> + <input type="submit" value="Upload" onclick="SetAction();" /> + </form> + </td> + </tr> + </table> + <br /> + URL: <span id="eUrl"></span> + </td> + </tr> + <tr> + <td height="100%" valign="top"> + <iframe id="eRunningFrame" src="../../../../fckblank.html" name="eRunningFrame" width="100%" + height="100%"></iframe> + </td> + </tr> + </table> +</body> +</html> diff --git a/htdocs/includes/fpdf/code39ext/ex.php b/htdocs/includes/fpdf/code39ext/ex.php index bb7a7defbcd5084c472c54f5ed4adafd72807e11..2e03a2a0bb87245ae50d67166ff70f5e59847aa8 100755 --- a/htdocs/includes/fpdf/code39ext/ex.php +++ b/htdocs/includes/fpdf/code39ext/ex.php @@ -1,9 +1,9 @@ -<?php -define('FPDF_FONTPATH','font/'); -require('code39.php'); - -$pdf=new PDF_Code39(); -$pdf->AddPage(); -$pdf->Code39(60, 30, 'Code 39'); -$pdf->Output(); -?> +<?php +define('FPDF_FONTPATH','font/'); +require('code39.php'); + +$pdf=new PDF_Code39(); +$pdf->AddPage(); +$pdf->Code39(60, 30, 'Code 39'); +$pdf->Output(); +?> diff --git a/htdocs/includes/fpdf/code39ext/info.htm b/htdocs/includes/fpdf/code39ext/info.htm index 6cc445f975514ad20cd74539671e7414da75223c..43d0ae87e188c08dd4d9c351a6c7d439fb38961b 100755 --- a/htdocs/includes/fpdf/code39ext/info.htm +++ b/htdocs/includes/fpdf/code39ext/info.htm @@ -1,28 +1,28 @@ -<HTML> -<HEAD> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> -<TITLE>Extended Code 39 barcodes</TITLE> -<STYLE> -BODY {font-family:"Times New Roman",serif} -H2 {color:#4000A0} -.st {font-weight:bold; color:#900000} -</STYLE> -</HEAD> -<BODY> -<H2>Extended Code 39 barcodes</H2> -<H4 CLASS="st">Informations</H4>Author: <A HREF="mailto:ehavet@yahoo.fr?subject=Extended%20Code%2039%20barcodes">Emmanuel Havet</A><BR>License: Freeware -<H4 CLASS="st">Description</H4>This script supports both standard and extended Code 39 barcodes. The extended mode gives access -to the full ASCII range (from 0 to 127). The script also gives the possibility to add a checksum.<BR> -<BR> -<TT>Code39(<B>float</B> x, <B>float</B> y, <B>string</B> code [, <B>boolean</B> ext [, <B>boolean</B> cks [, <B>float</B> w [, <B>float</B> h [, <B>boolean</B> wide]]]]])</TT><BR> -<BR> -<TT><U>x</U></TT>: abscissa<BR> -<TT><U>y</U></TT>: ordinate<BR> -<TT><U>code</U></TT>: barcode value<BR> -<TT><U>ext</U></TT>: indicates if extended mode must be used (<TT>true</TT> by default)<BR> -<TT><U>cks</U></TT>: indicates if a checksum must be appended (<TT>false</TT> by default)<BR> -<TT><U>w</U></TT>: width of a narrow bar (<TT>0.4</TT> by default)<BR> -<TT><U>h</U></TT>: height of bars (<TT>20</TT> by default)<BR> -<TT><U>wide</U></TT>: indicates if ratio between wide and narrow bars is high; if yes, ratio is 3, if no, it's 2 (<TT>true</TT> by default) -</BODY> -</HTML> +<HTML> +<HEAD> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> +<TITLE>Extended Code 39 barcodes</TITLE> +<STYLE> +BODY {font-family:"Times New Roman",serif} +H2 {color:#4000A0} +.st {font-weight:bold; color:#900000} +</STYLE> +</HEAD> +<BODY> +<H2>Extended Code 39 barcodes</H2> +<H4 CLASS="st">Informations</H4>Author: <A HREF="mailto:ehavet@yahoo.fr?subject=Extended%20Code%2039%20barcodes">Emmanuel Havet</A><BR>License: Freeware +<H4 CLASS="st">Description</H4>This script supports both standard and extended Code 39 barcodes. The extended mode gives access +to the full ASCII range (from 0 to 127). The script also gives the possibility to add a checksum.<BR> +<BR> +<TT>Code39(<B>float</B> x, <B>float</B> y, <B>string</B> code [, <B>boolean</B> ext [, <B>boolean</B> cks [, <B>float</B> w [, <B>float</B> h [, <B>boolean</B> wide]]]]])</TT><BR> +<BR> +<TT><U>x</U></TT>: abscissa<BR> +<TT><U>y</U></TT>: ordinate<BR> +<TT><U>code</U></TT>: barcode value<BR> +<TT><U>ext</U></TT>: indicates if extended mode must be used (<TT>true</TT> by default)<BR> +<TT><U>cks</U></TT>: indicates if a checksum must be appended (<TT>false</TT> by default)<BR> +<TT><U>w</U></TT>: width of a narrow bar (<TT>0.4</TT> by default)<BR> +<TT><U>h</U></TT>: height of bars (<TT>20</TT> by default)<BR> +<TT><U>wide</U></TT>: indicates if ratio between wide and narrow bars is high; if yes, ratio is 3, if no, it's 2 (<TT>true</TT> by default) +</BODY> +</HTML> diff --git a/htdocs/includes/fpdf/fpdf/FAQ.htm b/htdocs/includes/fpdf/fpdf/FAQ.htm index 8ffe0dcbac5c0c5f34464c4d717acda5e67759b3..839dcc4b87588cecca909f80b09a3d57dc1f61c6 100644 --- a/htdocs/includes/fpdf/fpdf/FAQ.htm +++ b/htdocs/includes/fpdf/fpdf/FAQ.htm @@ -1,302 +1,302 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<HTML> -<HEAD> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> -<TITLE>FAQ</TITLE> -<LINK TYPE="text/css" REL="stylesheet" HREF="fpdf.css"> -</HEAD> -<BODY> -<H2>FAQ</H2> -<UL STYLE="list-style-type:none; margin-left:0; padding-left:0; margin-bottom:2.2em"> -<LI><B>1.</B> <A HREF='#1'>Quelle est exactement la licence de FPDF ? Y a-t-il des restrictions d'utilisation ?</A> -<LI><B>2.</B> <A HREF='#2'>Lorsque j'essaie de cr�er un PDF, plein de caract�res bizarres s'affichent � l'�cran.</A> -<LI><B>3.</B> <A HREF='#3'>J'essaie de g�n�rer un PDF et IE m'affiche une page blanche. Que se passe-t-il ?</A> -<LI><B>4.</B> <A HREF='#4'>J'envoie des param�tres en utilisant la m�thode POST et les valeurs n'apparaissent pas dans le PDF.</A> -<LI><B>5.</B> <A HREF='#5'>Lorsque j'utilise une session PHP, IE n'affiche plus mon PDF mais propose de le t�l�charger.</A> -<LI><B>6.</B> <A HREF='#6'>Quand je suis en SSL, IE n'arrive pas � ouvrir le PDF.</A> -<LI><B>7.</B> <A HREF='#7'>Quand j'ex�cute un script j'obtiens le message "FPDF error: Don't alter the locale before including class file".</A> -<LI><B>8.</B> <A HREF='#8'>J'essaie de mettre un PNG et Acrobat me dit "Une erreur est survenue lors du traitement d'une page. Une erreur d'affichage est survenue".</A> -<LI><B>9.</B> <A HREF='#9'>J'ai l'erreur suivante quand j'essaie de g�n�rer un PDF : Warning: Cannot add header information - headers already sent by (output started at script.php:X)</A> -<LI><B>10.</B> <A HREF='#10'>J'essaie d'afficher une variable dans la m�thode Header mais rien ne s'imprime.</A> -<LI><B>11.</B> <A HREF='#11'>J'ai d�fini les m�thodes Header et Footer dans ma classe PDF mais rien ne s'affiche.</A> -<LI><B>12.</B> <A HREF='#12'>Je n'arrive pas � faire de retour � la ligne. J'ai bien mis \n dans la cha�ne imprim�e par MultiCell mais �a ne marche pas.</A> -<LI><B>13.</B> <A HREF='#13'>J'essaie de mettre le caract�re euro mais je n'y arrive pas.</A> -<LI><B>14.</B> <A HREF='#14'>Je dessine un cadre avec des dimensions tr�s pr�cises, mais � l'impression je constate des �carts.</A> -<LI><B>15.</B> <A HREF='#15'>Je voudrais utiliser toute la surface de la page mais � l'impression j'ai toujours des marges. Comment les enlever ?</A> -<LI><B>16.</B> <A HREF='#16'>Quelle est la taille limite des fichiers que je peux g�n�rer avec FPDF ?</A> -<LI><B>17.</B> <A HREF='#17'>Est-ce que je peux modifier un PDF avec FPDF ?</A> -<LI><B>18.</B> <A HREF='#18'>Je voudrais faire un moteur de recherche en PHP et indexer des PDF. Est-ce que je peux le faire avec FPDF ?</A> -<LI><B>19.</B> <A HREF='#19'>Est-ce que je peux transformer une page HTML en PDF avec FPDF ?</A> -<LI><B>20.</B> <A HREF='#20'>Est-ce que je peux concat�ner des PDF avec FPDF ?</A> -</UL> -<P><A NAME='1'><B>1.</B></A> <SPAN CLASS='st'>Quelle est exactement la licence de FPDF ? Y a-t-il des restrictions d'utilisation ?</SPAN></P> -FPDF est Freeware (c'est indiqu� au d�but du fichier source). Il n'y a pas de restriction -d'usage. Vous pouvez l'incorporer librement dans votre application (commerciale ou non), avec -ou sans modification. Vous pouvez �galement le redistribuer. -<P><A NAME='2'><B>2.</B></A> <SPAN CLASS='st'>Lorsque j'essaie de cr�er un PDF, plein de caract�res bizarres s'affichent � l'�cran.</SPAN></P> -Ces caract�res "bizarres" sont en fait le contenu r�el du PDF. Ce comportement est un bug d'IE. -Lorsqu'il re�oit d'abord une page HTML, puis un PDF � partir de la m�me URL, il l'affiche -directement sans lancer le plug-in Acrobat. Cela arrive fr�quemment en cours de d�veloppement : -� la moindre erreur de script, une page HTML est envoy�e, et apr�s correction, le PDF arrive. -<BR> -Pour r�soudre le probl�me, il suffit de fermer IE et de le relancer. On peut aussi aller sur -une autre URL et revenir. -<BR> -Pour �viter ce genre de d�sagr�ment durant le d�veloppement, on peut g�n�rer le PDF directement -dans un fichier et l'ouvrir via l'explorateur. -<P><A NAME='3'><B>3.</B></A> <SPAN CLASS='st'>J'essaie de g�n�rer un PDF et IE m'affiche une page blanche. Que se passe-t-il ?</SPAN></P> -Tout d'abord, v�rifiez que vous n'envoyez rien au navigateur apr�s le PDF (m�me pas un espace -ou un retour-chariot). Vous pouvez mettre un exit juste apr�s l'appel � la m�thode Output() -pour en �tre s�r. -<BR> -Si ce n'est pas �a, c'est que vous �tes victime du syndrome de la "page blanche". IE utilis� -en conjonction avec le plug-in Acrobat souffre de tr�s nombreux bugs, quelles que soient les -versions. Essayez de tester votre application avec le plus de versions d'IE possible (en tout cas -si elle est sur Internet). Le probl�me survient surtout lorsqu'on utilise la m�thode POST, c'est -pourquoi il est fortement d�conseill� de l'utiliser (d'autant qu'elle pose d'autres probl�mes, -voir la question suivante). Le GET marche mieux mais peut �chouer lorsque l'URL devient trop -longue : il ne faut pas d�passer 45 caract�res pour la query string. Il existe cependant une -astuce pour d�passer cette limite : terminer l'URL par .pdf, ce qui trompe IE. Si vous utilisez -un formulaire, il suffit de rajouter un champ cach� en derni�re position : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -<INPUT TYPE="HIDDEN" NAME="ext" VALUE=".pdf"> -</TT> -</TD></TR></TABLE><BR> -L'utilisation de session PHP cause �galement souvent des dysfonctionnements (il faut �viter -d'envoyer des en-t�tes HTTP emp�chant la mise en cache). Voir la question 5 pour un moyen -de r�soudre le probl�me. -<BR> -<BR> -Pour �viter tous ces probl�mes de mani�re fiable, il existe deux principales techniques : -<BR> -<BR> -- D�sactiver le plug-in et utiliser Acrobat comme application externe. Pour cela, lancez -Acrobat ; dans le menu Fichier, Pr�f�rences, G�n�rales, d�sactivez l'option "Int�grer au -navigateur Web" (pour Acrobat 5 : Edition, Pr�f�rences, Options, "Afficher dans le navigateur"). -Puis, lorsque vous r�cup�rez un PDF dans IE, ce dernier affiche la bo�te "Ouvrir ce fichier" ou -"Enregistrer ce fichier". D�cochez la case "Toujours demander avant d'ouvrir ce type de fichier" -et choisissez Ouvrir. Dor�navant les PDF s'ouvriront automatiquement dans une fen�tre Acrobat -ind�pendante. -<BR> -L'inconv�nient de la m�thode est qu'il faut toucher � la configuration du poste client, ce -qu'on peut faire en intranet mais pas pour Internet. -<BR> -<BR> -- Utiliser une technique de redirection. Le principe consiste � g�n�rer le PDF dans un fichier -temporaire sur le serveur et � rediriger le client dessus (en utilisant du JavaScript, pas -l'en-t�te HTTP Location qui pose aussi des probl�mes). Par exemple, � la fin du script, on -peut mettre : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -//Détermination d'un nom de fichier temporaire dans le répertoire courant<BR> -$file=basename(tempnam(getcwd(),'tmp'));<BR> -//Sauvegarde du PDF dans le fichier<BR> -$pdf->Output($file);<BR> -//Redirection JavaScript<BR> -echo "<HTML><SCRIPT>document.location='getpdf.php?f=$file';</SCRIPT></HTML>"; -</TT> -</TD></TR></TABLE><BR> -Puis ceci dans getpdf.php : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -<?php<BR> -$f=$HTTP_GET_VARS['f'];<BR> -//Contrôle du fichier (à ne pas oublier !)<BR> -if(substr($f,0,3)!='tmp' or strpos($f,'/') or strpos($f,'\\'))<BR> - die("Nom de fichier incorrect");<BR> -if(!file_exists($f))<BR> - die("Le fichier n'existe pas");<BR> -//Traitement de la requête spéciale IE au cas où<BR> -if($HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype')<BR> -{<BR> - Header('Content-Type: application/pdf');<BR> - exit;<BR> -}<BR> -//Envoi du PDF<BR> -Header('Content-Type: application/pdf');<BR> -Header('Content-Length: '.filesize($f));<BR> -readfile($f);<BR> -//Suppression du fichier<BR> -unlink($f);<BR> -exit;<BR> -?> -</TT> -</TD></TR></TABLE><BR> -Cette m�thode fonctionne dans la plupart des cas, mais pose encore des probl�mes avec IE6. La -m�thode "ultime" consiste � rediriger directement sur le fichier temporaire. Ce dernier doit -donc avoir l'extension .pdf : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -//Détermination d'un nom de fichier temporaire dans le répertoire courant<BR> -$file=basename(tempnam(getcwd(),'tmp'));<BR> -rename($file,$file.'.pdf');<BR> -$file.='.pdf';<BR> -//Sauvegarde du PDF dans le fichier<BR> -$pdf->Output($file);<BR> -//Redirection JavaScript<BR> -echo "<HTML><SCRIPT>document.location='$file';</SCRIPT></HTML>"; -</TT> -</TD></TR></TABLE><BR> -Cette m�thode transforme un PDF dynamique en PDF statique et �vite ainsi tous les ennuis. -Par contre, il faut pr�voir une proc�dure de nettoyage pour effacer les fichiers temporaires. -Par exemple : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -function CleanFiles($dir)<BR> -{<BR> - //Efface les fichiers temporaires<BR> - $t=time();<BR> - $h=opendir($dir);<BR> - while($file=readdir($h))<BR> - {<BR> - if(substr($file,0,3)=='tmp' and substr($file,-4)=='.pdf')<BR> - {<BR> - $path=$dir.'/'.$file;<BR> - if($t-filemtime($path)>3600)<BR> - @unlink($path);<BR> - }<BR> - }<BR> - closedir($h);<BR> -} -</TT> -</TD></TR></TABLE><BR> -Cette fonction efface tous les fichiers de la forme tmp*.pdf dans le r�pertoire sp�cifi� qui -datent de plus d'une heure. Vous pouvez l'appeler o� vous voulez, par exemple dans le script -qui g�n�re le PDF. -<BR> -<BR> -Remarque : il est n�cessaire d'ouvrir une nouvelle fen�tre pour le PDF, car on ne peut plus -revenir en arri�re � cause de la redirection. -<P><A NAME='4'><B>4.</B></A> <SPAN CLASS='st'>J'envoie des param�tres en utilisant la m�thode POST et les valeurs n'apparaissent pas dans le PDF.</SPAN></P> -C'est un probl�me qui affecte certaines versions d'IE (en particulier la premi�re 5.5). Voir la -question pr�c�dente pour les moyens de le contourner. -<P><A NAME='5'><B>5.</B></A> <SPAN CLASS='st'>Lorsque j'utilise une session PHP, IE n'affiche plus mon PDF mais propose de le t�l�charger.</SPAN></P> -C'est un probl�me qui affecte certaines versions d'IE. Pour le contourner, ajoutez la ligne -suivante avant session_start() :<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -session_cache_limiter('private'); -</TT> -</TD></TR></TABLE><BR> -ou bien faites une redirection comme expliqu� � la question 3. -<P><A NAME='6'><B>6.</B></A> <SPAN CLASS='st'>Quand je suis en SSL, IE n'arrive pas � ouvrir le PDF.</SPAN></P> -Le probl�me peut �tre r�solu en ajoutant cette ligne :<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -Header('Pragma: public'); -</TT> -</TD></TR></TABLE><BR> - -<P><A NAME='7'><B>7.</B></A> <SPAN CLASS='st'>Quand j'ex�cute un script j'obtiens le message "FPDF error: Don't alter the locale before including class file".</SPAN></P> -Lorsqu'on configure le s�parateur d�cimal comme virgule avant d'inclure un fichier, il y a un -<A HREF="http://bugs.php.net/bug.php?id=17105" TARGET="_blank">bug</A> dans certaines versions de PHP et les -nombres d�cimaux sont tronqu�s. Il ne faut donc pas faire d'appel � setlocale() avant d'inclure la -classe. Sous Unix, il ne faut pas non plus d�finir la variable d'environnement LC_ALL, car cela -est �quivalent � faire un appel � setlocale(). -<P><A NAME='8'><B>8.</B></A> <SPAN CLASS='st'>J'essaie de mettre un PNG et Acrobat me dit "Une erreur est survenue lors du traitement d'une page. Une erreur d'affichage est survenue".</SPAN></P> -Acrobat 5 a un bug et ne peut pas afficher les images transparentes monochromes (i.e. avec 1 bit par pixel). -Enlevez la transparence ou passez votre image en 16 couleurs (4 bits par pixel) ou plus. -<P><A NAME='9'><B>9.</B></A> <SPAN CLASS='st'>J'ai l'erreur suivante quand j'essaie de g�n�rer un PDF : Warning: Cannot add header information - headers already sent by (output started at script.php:X)</SPAN></P> -Il ne faut rien envoyer d'autre au navigateur que le PDF lui-m�me : pas d'HTML, pas d'espace, pas -de retour-chariot, ni avant ni apr�s. Le script envoie quelque chose � la ligne X. -<P><A NAME='10'><B>10.</B></A> <SPAN CLASS='st'>J'essaie d'afficher une variable dans la m�thode Header mais rien ne s'imprime.</SPAN></P> -Il faut utiliser le mot-cl� <TT>global</TT>, par exemple : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -function Header()<BR> -{<BR> - global $titre;<BR> -<BR> - $this->SetFont('Arial','B',15);<BR> - $this->Cell(0,10,$titre,1,1,'C');<BR> -} -</TT> -</TD></TR></TABLE><BR> - -<P><A NAME='11'><B>11.</B></A> <SPAN CLASS='st'>J'ai d�fini les m�thodes Header et Footer dans ma classe PDF mais rien ne s'affiche.</SPAN></P> -Il faut cr�er un objet de la classe PDF et non pas FPDF :<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -$pdf=new PDF(); -</TT> -</TD></TR></TABLE><BR> - -<P><A NAME='12'><B>12.</B></A> <SPAN CLASS='st'>Je n'arrive pas � faire de retour � la ligne. J'ai bien mis \n dans la cha�ne imprim�e par MultiCell mais �a ne marche pas.</SPAN></P> -Il faut mettre la cha�ne entre guillemets et non pas entre apostrophes. -<P><A NAME='13'><B>13.</B></A> <SPAN CLASS='st'>J'essaie de mettre le caract�re euro mais je n'y arrive pas.</SPAN></P> -Pour les polices standard, le caract�re euro a pour code 128. Vous pouvez par commodit� d�finir -une constante comme suit : -<BR> -<BR> -<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> -<TT> -define('EURO',chr(128)); -</TT> -</TD></TR></TABLE><BR> -Note : Acrobat 4 ou sup�rieur est requis pour afficher l'euro. -<P><A NAME='14'><B>14.</B></A> <SPAN CLASS='st'>Je dessine un cadre avec des dimensions tr�s pr�cises, mais � l'impression je constate des �carts.</SPAN></P> -Pour respecter les dimensions, il faut d�cocher la case "Ajuster" dans la bo�te de dialogue -d'impression. -<P><A NAME='15'><B>15.</B></A> <SPAN CLASS='st'>Je voudrais utiliser toute la surface de la page mais � l'impression j'ai toujours des marges. Comment les enlever ?</SPAN></P> -Les imprimantes ont toutes des marges physiques (variables en fonction du mod�le), il est donc -impossible de les supprimer et d'imprimer sur la totalit� de la page. -<P><A NAME='16'><B>16.</B></A> <SPAN CLASS='st'>Quelle est la taille limite des fichiers que je peux g�n�rer avec FPDF ?</SPAN></P> -Il n'y a pas de limite particuli�re. Il existe cependant certaines contraintes : -<BR> -<BR> -- La taille m�moire allou�e par d�faut aux scripts PHP est de 8 Mo. Pour de tr�s gros -documents, en particulier avec des images, cette limite peut �tre atteinte (le fichier �tant -construit en m�moire). Elle est param�tr�e dans php.ini. -<BR> -<BR> -- Le temps d'ex�cution allou� par d�faut est de 30 secondes. Cette limite peut bien entendu -�tre facilement d�pass�e. Elle est param�tr�e dans php.ini et peut �tre �ventuellement modifi�e -� l'ex�cution par set_time_limit(). -<BR> -<BR> -- Les navigateurs ont g�n�ralement un time-out de 5 minutes. Si vous envoyez le PDF directement -au navigateur et que vous d�passez cette limite, il sera perdu. Il est donc conseill� pour les -tr�s gros documents de les g�n�rer dans un fichier, et d'envoyer des donn�es de temps en temps -au navigateur (par exemple page 1, page 2... en utilisant flush() pour forcer l'envoi). -Lorsque le fichier est termin�, vous pouvez effectuer une redirection dessus avec JavaScript -ou bien cr�er un lien. -<BR> -Remarque : m�me lorsque le navigateur part en time-out, il est possible que le script continue -� s'ex�cuter sur le serveur. -<P><A NAME='17'><B>17.</B></A> <SPAN CLASS='st'>Est-ce que je peux modifier un PDF avec FPDF ?</SPAN></P> -Il est possible d'importer un PDF existant gr�ce � l'extension FPDI :<BR> -<BR> -<A HREF="http://fpdi.setasign.de" TARGET="_blank">http://fpdi.setasign.de</A> -<P><A NAME='18'><B>18.</B></A> <SPAN CLASS='st'>Je voudrais faire un moteur de recherche en PHP et indexer des PDF. Est-ce que je peux le faire avec FPDF ?</SPAN></P> -Non. Par contre il existe un utilitaire GPL en C, pdftotext, capable d'extraire le contenu -textuel d'un PDF. Il est fourni avec l'archive de Xpdf :<BR> -<BR> -<A HREF="http://www.foolabs.com/xpdf/" TARGET="_blank">http://www.foolabs.com/xpdf/</A> -<P><A NAME='19'><B>19.</B></A> <SPAN CLASS='st'>Est-ce que je peux transformer une page HTML en PDF avec FPDF ?</SPAN></P> -Non, on ne peut convertir que de l'HTML tr�s simple, pas des pages r�elles. Par contre il -existe un utilitaire GPL en C, htmldoc, qui permet de le faire et donne de bons r�sultats :<BR> -<BR> -<A HREF="http://www.htmldoc.org" TARGET="_blank">http://www.htmldoc.org</A> -<P><A NAME='20'><B>20.</B></A> <SPAN CLASS='st'>Est-ce que je peux concat�ner des PDF avec FPDF ?</SPAN></P> -Non. Par contre il existe des utilitaires gratuits pour le faire :<BR> -<BR> -<A HREF="http://thierry.schmit.free.fr/dev/mbtPdfAsm/mbtPdfAsm2.html" TARGET="_blank">http://thierry.schmit.free.fr/dev/mbtPdfAsm/mbtPdfAsm2.html</A><BR> -<A HREF="http://www.accesspdf.com/pdftk/">http://www.accesspdf.com/pdftk/</A> -</BODY> -</HTML> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<HTML> +<HEAD> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> +<TITLE>FAQ</TITLE> +<LINK TYPE="text/css" REL="stylesheet" HREF="fpdf.css"> +</HEAD> +<BODY> +<H2>FAQ</H2> +<UL STYLE="list-style-type:none; margin-left:0; padding-left:0; margin-bottom:2.2em"> +<LI><B>1.</B> <A HREF='#1'>Quelle est exactement la licence de FPDF ? Y a-t-il des restrictions d'utilisation ?</A> +<LI><B>2.</B> <A HREF='#2'>Lorsque j'essaie de cr�er un PDF, plein de caract�res bizarres s'affichent � l'�cran.</A> +<LI><B>3.</B> <A HREF='#3'>J'essaie de g�n�rer un PDF et IE m'affiche une page blanche. Que se passe-t-il ?</A> +<LI><B>4.</B> <A HREF='#4'>J'envoie des param�tres en utilisant la m�thode POST et les valeurs n'apparaissent pas dans le PDF.</A> +<LI><B>5.</B> <A HREF='#5'>Lorsque j'utilise une session PHP, IE n'affiche plus mon PDF mais propose de le t�l�charger.</A> +<LI><B>6.</B> <A HREF='#6'>Quand je suis en SSL, IE n'arrive pas � ouvrir le PDF.</A> +<LI><B>7.</B> <A HREF='#7'>Quand j'ex�cute un script j'obtiens le message "FPDF error: Don't alter the locale before including class file".</A> +<LI><B>8.</B> <A HREF='#8'>J'essaie de mettre un PNG et Acrobat me dit "Une erreur est survenue lors du traitement d'une page. Une erreur d'affichage est survenue".</A> +<LI><B>9.</B> <A HREF='#9'>J'ai l'erreur suivante quand j'essaie de g�n�rer un PDF : Warning: Cannot add header information - headers already sent by (output started at script.php:X)</A> +<LI><B>10.</B> <A HREF='#10'>J'essaie d'afficher une variable dans la m�thode Header mais rien ne s'imprime.</A> +<LI><B>11.</B> <A HREF='#11'>J'ai d�fini les m�thodes Header et Footer dans ma classe PDF mais rien ne s'affiche.</A> +<LI><B>12.</B> <A HREF='#12'>Je n'arrive pas � faire de retour � la ligne. J'ai bien mis \n dans la cha�ne imprim�e par MultiCell mais �a ne marche pas.</A> +<LI><B>13.</B> <A HREF='#13'>J'essaie de mettre le caract�re euro mais je n'y arrive pas.</A> +<LI><B>14.</B> <A HREF='#14'>Je dessine un cadre avec des dimensions tr�s pr�cises, mais � l'impression je constate des �carts.</A> +<LI><B>15.</B> <A HREF='#15'>Je voudrais utiliser toute la surface de la page mais � l'impression j'ai toujours des marges. Comment les enlever ?</A> +<LI><B>16.</B> <A HREF='#16'>Quelle est la taille limite des fichiers que je peux g�n�rer avec FPDF ?</A> +<LI><B>17.</B> <A HREF='#17'>Est-ce que je peux modifier un PDF avec FPDF ?</A> +<LI><B>18.</B> <A HREF='#18'>Je voudrais faire un moteur de recherche en PHP et indexer des PDF. Est-ce que je peux le faire avec FPDF ?</A> +<LI><B>19.</B> <A HREF='#19'>Est-ce que je peux transformer une page HTML en PDF avec FPDF ?</A> +<LI><B>20.</B> <A HREF='#20'>Est-ce que je peux concat�ner des PDF avec FPDF ?</A> +</UL> +<P><A NAME='1'><B>1.</B></A> <SPAN CLASS='st'>Quelle est exactement la licence de FPDF ? Y a-t-il des restrictions d'utilisation ?</SPAN></P> +FPDF est Freeware (c'est indiqu� au d�but du fichier source). Il n'y a pas de restriction +d'usage. Vous pouvez l'incorporer librement dans votre application (commerciale ou non), avec +ou sans modification. Vous pouvez �galement le redistribuer. +<P><A NAME='2'><B>2.</B></A> <SPAN CLASS='st'>Lorsque j'essaie de cr�er un PDF, plein de caract�res bizarres s'affichent � l'�cran.</SPAN></P> +Ces caract�res "bizarres" sont en fait le contenu r�el du PDF. Ce comportement est un bug d'IE. +Lorsqu'il re�oit d'abord une page HTML, puis un PDF � partir de la m�me URL, il l'affiche +directement sans lancer le plug-in Acrobat. Cela arrive fr�quemment en cours de d�veloppement : +� la moindre erreur de script, une page HTML est envoy�e, et apr�s correction, le PDF arrive. +<BR> +Pour r�soudre le probl�me, il suffit de fermer IE et de le relancer. On peut aussi aller sur +une autre URL et revenir. +<BR> +Pour �viter ce genre de d�sagr�ment durant le d�veloppement, on peut g�n�rer le PDF directement +dans un fichier et l'ouvrir via l'explorateur. +<P><A NAME='3'><B>3.</B></A> <SPAN CLASS='st'>J'essaie de g�n�rer un PDF et IE m'affiche une page blanche. Que se passe-t-il ?</SPAN></P> +Tout d'abord, v�rifiez que vous n'envoyez rien au navigateur apr�s le PDF (m�me pas un espace +ou un retour-chariot). Vous pouvez mettre un exit juste apr�s l'appel � la m�thode Output() +pour en �tre s�r. +<BR> +Si ce n'est pas �a, c'est que vous �tes victime du syndrome de la "page blanche". IE utilis� +en conjonction avec le plug-in Acrobat souffre de tr�s nombreux bugs, quelles que soient les +versions. Essayez de tester votre application avec le plus de versions d'IE possible (en tout cas +si elle est sur Internet). Le probl�me survient surtout lorsqu'on utilise la m�thode POST, c'est +pourquoi il est fortement d�conseill� de l'utiliser (d'autant qu'elle pose d'autres probl�mes, +voir la question suivante). Le GET marche mieux mais peut �chouer lorsque l'URL devient trop +longue : il ne faut pas d�passer 45 caract�res pour la query string. Il existe cependant une +astuce pour d�passer cette limite : terminer l'URL par .pdf, ce qui trompe IE. Si vous utilisez +un formulaire, il suffit de rajouter un champ cach� en derni�re position : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +<INPUT TYPE="HIDDEN" NAME="ext" VALUE=".pdf"> +</TT> +</TD></TR></TABLE><BR> +L'utilisation de session PHP cause �galement souvent des dysfonctionnements (il faut �viter +d'envoyer des en-t�tes HTTP emp�chant la mise en cache). Voir la question 5 pour un moyen +de r�soudre le probl�me. +<BR> +<BR> +Pour �viter tous ces probl�mes de mani�re fiable, il existe deux principales techniques : +<BR> +<BR> +- D�sactiver le plug-in et utiliser Acrobat comme application externe. Pour cela, lancez +Acrobat ; dans le menu Fichier, Pr�f�rences, G�n�rales, d�sactivez l'option "Int�grer au +navigateur Web" (pour Acrobat 5 : Edition, Pr�f�rences, Options, "Afficher dans le navigateur"). +Puis, lorsque vous r�cup�rez un PDF dans IE, ce dernier affiche la bo�te "Ouvrir ce fichier" ou +"Enregistrer ce fichier". D�cochez la case "Toujours demander avant d'ouvrir ce type de fichier" +et choisissez Ouvrir. Dor�navant les PDF s'ouvriront automatiquement dans une fen�tre Acrobat +ind�pendante. +<BR> +L'inconv�nient de la m�thode est qu'il faut toucher � la configuration du poste client, ce +qu'on peut faire en intranet mais pas pour Internet. +<BR> +<BR> +- Utiliser une technique de redirection. Le principe consiste � g�n�rer le PDF dans un fichier +temporaire sur le serveur et � rediriger le client dessus (en utilisant du JavaScript, pas +l'en-t�te HTTP Location qui pose aussi des probl�mes). Par exemple, � la fin du script, on +peut mettre : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +//Détermination d'un nom de fichier temporaire dans le répertoire courant<BR> +$file=basename(tempnam(getcwd(),'tmp'));<BR> +//Sauvegarde du PDF dans le fichier<BR> +$pdf->Output($file);<BR> +//Redirection JavaScript<BR> +echo "<HTML><SCRIPT>document.location='getpdf.php?f=$file';</SCRIPT></HTML>"; +</TT> +</TD></TR></TABLE><BR> +Puis ceci dans getpdf.php : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +<?php<BR> +$f=$HTTP_GET_VARS['f'];<BR> +//Contrôle du fichier (à ne pas oublier !)<BR> +if(substr($f,0,3)!='tmp' or strpos($f,'/') or strpos($f,'\\'))<BR> + die("Nom de fichier incorrect");<BR> +if(!file_exists($f))<BR> + die("Le fichier n'existe pas");<BR> +//Traitement de la requête spéciale IE au cas où<BR> +if($HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype')<BR> +{<BR> + Header('Content-Type: application/pdf');<BR> + exit;<BR> +}<BR> +//Envoi du PDF<BR> +Header('Content-Type: application/pdf');<BR> +Header('Content-Length: '.filesize($f));<BR> +readfile($f);<BR> +//Suppression du fichier<BR> +unlink($f);<BR> +exit;<BR> +?> +</TT> +</TD></TR></TABLE><BR> +Cette m�thode fonctionne dans la plupart des cas, mais pose encore des probl�mes avec IE6. La +m�thode "ultime" consiste � rediriger directement sur le fichier temporaire. Ce dernier doit +donc avoir l'extension .pdf : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +//Détermination d'un nom de fichier temporaire dans le répertoire courant<BR> +$file=basename(tempnam(getcwd(),'tmp'));<BR> +rename($file,$file.'.pdf');<BR> +$file.='.pdf';<BR> +//Sauvegarde du PDF dans le fichier<BR> +$pdf->Output($file);<BR> +//Redirection JavaScript<BR> +echo "<HTML><SCRIPT>document.location='$file';</SCRIPT></HTML>"; +</TT> +</TD></TR></TABLE><BR> +Cette m�thode transforme un PDF dynamique en PDF statique et �vite ainsi tous les ennuis. +Par contre, il faut pr�voir une proc�dure de nettoyage pour effacer les fichiers temporaires. +Par exemple : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +function CleanFiles($dir)<BR> +{<BR> + //Efface les fichiers temporaires<BR> + $t=time();<BR> + $h=opendir($dir);<BR> + while($file=readdir($h))<BR> + {<BR> + if(substr($file,0,3)=='tmp' and substr($file,-4)=='.pdf')<BR> + {<BR> + $path=$dir.'/'.$file;<BR> + if($t-filemtime($path)>3600)<BR> + @unlink($path);<BR> + }<BR> + }<BR> + closedir($h);<BR> +} +</TT> +</TD></TR></TABLE><BR> +Cette fonction efface tous les fichiers de la forme tmp*.pdf dans le r�pertoire sp�cifi� qui +datent de plus d'une heure. Vous pouvez l'appeler o� vous voulez, par exemple dans le script +qui g�n�re le PDF. +<BR> +<BR> +Remarque : il est n�cessaire d'ouvrir une nouvelle fen�tre pour le PDF, car on ne peut plus +revenir en arri�re � cause de la redirection. +<P><A NAME='4'><B>4.</B></A> <SPAN CLASS='st'>J'envoie des param�tres en utilisant la m�thode POST et les valeurs n'apparaissent pas dans le PDF.</SPAN></P> +C'est un probl�me qui affecte certaines versions d'IE (en particulier la premi�re 5.5). Voir la +question pr�c�dente pour les moyens de le contourner. +<P><A NAME='5'><B>5.</B></A> <SPAN CLASS='st'>Lorsque j'utilise une session PHP, IE n'affiche plus mon PDF mais propose de le t�l�charger.</SPAN></P> +C'est un probl�me qui affecte certaines versions d'IE. Pour le contourner, ajoutez la ligne +suivante avant session_start() :<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +session_cache_limiter('private'); +</TT> +</TD></TR></TABLE><BR> +ou bien faites une redirection comme expliqu� � la question 3. +<P><A NAME='6'><B>6.</B></A> <SPAN CLASS='st'>Quand je suis en SSL, IE n'arrive pas � ouvrir le PDF.</SPAN></P> +Le probl�me peut �tre r�solu en ajoutant cette ligne :<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +Header('Pragma: public'); +</TT> +</TD></TR></TABLE><BR> + +<P><A NAME='7'><B>7.</B></A> <SPAN CLASS='st'>Quand j'ex�cute un script j'obtiens le message "FPDF error: Don't alter the locale before including class file".</SPAN></P> +Lorsqu'on configure le s�parateur d�cimal comme virgule avant d'inclure un fichier, il y a un +<A HREF="http://bugs.php.net/bug.php?id=17105" TARGET="_blank">bug</A> dans certaines versions de PHP et les +nombres d�cimaux sont tronqu�s. Il ne faut donc pas faire d'appel � setlocale() avant d'inclure la +classe. Sous Unix, il ne faut pas non plus d�finir la variable d'environnement LC_ALL, car cela +est �quivalent � faire un appel � setlocale(). +<P><A NAME='8'><B>8.</B></A> <SPAN CLASS='st'>J'essaie de mettre un PNG et Acrobat me dit "Une erreur est survenue lors du traitement d'une page. Une erreur d'affichage est survenue".</SPAN></P> +Acrobat 5 a un bug et ne peut pas afficher les images transparentes monochromes (i.e. avec 1 bit par pixel). +Enlevez la transparence ou passez votre image en 16 couleurs (4 bits par pixel) ou plus. +<P><A NAME='9'><B>9.</B></A> <SPAN CLASS='st'>J'ai l'erreur suivante quand j'essaie de g�n�rer un PDF : Warning: Cannot add header information - headers already sent by (output started at script.php:X)</SPAN></P> +Il ne faut rien envoyer d'autre au navigateur que le PDF lui-m�me : pas d'HTML, pas d'espace, pas +de retour-chariot, ni avant ni apr�s. Le script envoie quelque chose � la ligne X. +<P><A NAME='10'><B>10.</B></A> <SPAN CLASS='st'>J'essaie d'afficher une variable dans la m�thode Header mais rien ne s'imprime.</SPAN></P> +Il faut utiliser le mot-cl� <TT>global</TT>, par exemple : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +function Header()<BR> +{<BR> + global $titre;<BR> +<BR> + $this->SetFont('Arial','B',15);<BR> + $this->Cell(0,10,$titre,1,1,'C');<BR> +} +</TT> +</TD></TR></TABLE><BR> + +<P><A NAME='11'><B>11.</B></A> <SPAN CLASS='st'>J'ai d�fini les m�thodes Header et Footer dans ma classe PDF mais rien ne s'affiche.</SPAN></P> +Il faut cr�er un objet de la classe PDF et non pas FPDF :<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +$pdf=new PDF(); +</TT> +</TD></TR></TABLE><BR> + +<P><A NAME='12'><B>12.</B></A> <SPAN CLASS='st'>Je n'arrive pas � faire de retour � la ligne. J'ai bien mis \n dans la cha�ne imprim�e par MultiCell mais �a ne marche pas.</SPAN></P> +Il faut mettre la cha�ne entre guillemets et non pas entre apostrophes. +<P><A NAME='13'><B>13.</B></A> <SPAN CLASS='st'>J'essaie de mettre le caract�re euro mais je n'y arrive pas.</SPAN></P> +Pour les polices standard, le caract�re euro a pour code 128. Vous pouvez par commodit� d�finir +une constante comme suit : +<BR> +<BR> +<TABLE WIDTH="100%" BGCOLOR="#E0E0E0"><TR><TD> +<TT> +define('EURO',chr(128)); +</TT> +</TD></TR></TABLE><BR> +Note : Acrobat 4 ou sup�rieur est requis pour afficher l'euro. +<P><A NAME='14'><B>14.</B></A> <SPAN CLASS='st'>Je dessine un cadre avec des dimensions tr�s pr�cises, mais � l'impression je constate des �carts.</SPAN></P> +Pour respecter les dimensions, il faut d�cocher la case "Ajuster" dans la bo�te de dialogue +d'impression. +<P><A NAME='15'><B>15.</B></A> <SPAN CLASS='st'>Je voudrais utiliser toute la surface de la page mais � l'impression j'ai toujours des marges. Comment les enlever ?</SPAN></P> +Les imprimantes ont toutes des marges physiques (variables en fonction du mod�le), il est donc +impossible de les supprimer et d'imprimer sur la totalit� de la page. +<P><A NAME='16'><B>16.</B></A> <SPAN CLASS='st'>Quelle est la taille limite des fichiers que je peux g�n�rer avec FPDF ?</SPAN></P> +Il n'y a pas de limite particuli�re. Il existe cependant certaines contraintes : +<BR> +<BR> +- La taille m�moire allou�e par d�faut aux scripts PHP est de 8 Mo. Pour de tr�s gros +documents, en particulier avec des images, cette limite peut �tre atteinte (le fichier �tant +construit en m�moire). Elle est param�tr�e dans php.ini. +<BR> +<BR> +- Le temps d'ex�cution allou� par d�faut est de 30 secondes. Cette limite peut bien entendu +�tre facilement d�pass�e. Elle est param�tr�e dans php.ini et peut �tre �ventuellement modifi�e +� l'ex�cution par set_time_limit(). +<BR> +<BR> +- Les navigateurs ont g�n�ralement un time-out de 5 minutes. Si vous envoyez le PDF directement +au navigateur et que vous d�passez cette limite, il sera perdu. Il est donc conseill� pour les +tr�s gros documents de les g�n�rer dans un fichier, et d'envoyer des donn�es de temps en temps +au navigateur (par exemple page 1, page 2... en utilisant flush() pour forcer l'envoi). +Lorsque le fichier est termin�, vous pouvez effectuer une redirection dessus avec JavaScript +ou bien cr�er un lien. +<BR> +Remarque : m�me lorsque le navigateur part en time-out, il est possible que le script continue +� s'ex�cuter sur le serveur. +<P><A NAME='17'><B>17.</B></A> <SPAN CLASS='st'>Est-ce que je peux modifier un PDF avec FPDF ?</SPAN></P> +Il est possible d'importer un PDF existant gr�ce � l'extension FPDI :<BR> +<BR> +<A HREF="http://fpdi.setasign.de" TARGET="_blank">http://fpdi.setasign.de</A> +<P><A NAME='18'><B>18.</B></A> <SPAN CLASS='st'>Je voudrais faire un moteur de recherche en PHP et indexer des PDF. Est-ce que je peux le faire avec FPDF ?</SPAN></P> +Non. Par contre il existe un utilitaire GPL en C, pdftotext, capable d'extraire le contenu +textuel d'un PDF. Il est fourni avec l'archive de Xpdf :<BR> +<BR> +<A HREF="http://www.foolabs.com/xpdf/" TARGET="_blank">http://www.foolabs.com/xpdf/</A> +<P><A NAME='19'><B>19.</B></A> <SPAN CLASS='st'>Est-ce que je peux transformer une page HTML en PDF avec FPDF ?</SPAN></P> +Non, on ne peut convertir que de l'HTML tr�s simple, pas des pages r�elles. Par contre il +existe un utilitaire GPL en C, htmldoc, qui permet de le faire et donne de bons r�sultats :<BR> +<BR> +<A HREF="http://www.htmldoc.org" TARGET="_blank">http://www.htmldoc.org</A> +<P><A NAME='20'><B>20.</B></A> <SPAN CLASS='st'>Est-ce que je peux concat�ner des PDF avec FPDF ?</SPAN></P> +Non. Par contre il existe des utilitaires gratuits pour le faire :<BR> +<BR> +<A HREF="http://thierry.schmit.free.fr/dev/mbtPdfAsm/mbtPdfAsm2.html" TARGET="_blank">http://thierry.schmit.free.fr/dev/mbtPdfAsm/mbtPdfAsm2.html</A><BR> +<A HREF="http://www.accesspdf.com/pdftk/">http://www.accesspdf.com/pdftk/</A> +</BODY> +</HTML> diff --git a/htdocs/includes/fpdf/fpdf/fpdf.css b/htdocs/includes/fpdf/fpdf/fpdf.css index 045a32e3722b6d458ff92e31fd4593c1eca136d0..d979baec29f0ca74a1af0aca7aff4efaa6a4454a 100644 --- a/htdocs/includes/fpdf/fpdf/fpdf.css +++ b/htdocs/includes/fpdf/fpdf/fpdf.css @@ -1,11 +1,11 @@ -BODY {font-family:times new roman,serif} -H2 {color:#4000A0} -P.demo {text-align:center; margin-top:-10px} -A.demo {text-decoration:none; font-weight:bold; color:#0000CC} -A.demo:link {text-decoration:none; font-weight:bold; color:#0000CC} -A.demo:hover {text-decoration:none; font-weight:bold; color:#0000FF} -A.demo:active {text-decoration:none; font-weight:bold; color:#0000FF} -.st {font-weight:bold; color:#900000} -.kw {color:#000080; font-weight:bold} -.str {color:#CC0000} -.cmt {color:#008000} +BODY {font-family:times new roman,serif} +H2 {color:#4000A0} +P.demo {text-align:center; margin-top:-10px} +A.demo {text-decoration:none; font-weight:bold; color:#0000CC} +A.demo:link {text-decoration:none; font-weight:bold; color:#0000CC} +A.demo:hover {text-decoration:none; font-weight:bold; color:#0000FF} +A.demo:active {text-decoration:none; font-weight:bold; color:#0000FF} +.st {font-weight:bold; color:#900000} +.kw {color:#000080; font-weight:bold} +.str {color:#CC0000} +.cmt {color:#008000} diff --git a/htdocs/includes/fpdf/fpdf/histo.htm b/htdocs/includes/fpdf/fpdf/histo.htm index 264aec27571c788c58d899ddac4b5c37fb339ba7..167b18edd09b4c64aa35e2cb48870c785dcca5b9 100644 --- a/htdocs/includes/fpdf/fpdf/histo.htm +++ b/htdocs/includes/fpdf/fpdf/histo.htm @@ -1,111 +1,111 @@ -<HTML> -<HEAD> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> -<TITLE>Historique</TITLE> -<LINK TYPE="text/css" REL="stylesheet" HREF="fpdf.css"> -</HEAD> -<BODY> -<H2>Historique</H2> -<B>v1.53</B> (31/12/2004) -<BLOCKQUOTE> -- Lorsque le sous-r�pertoire font se trouve dans le m�me r�pertoire que fpdf.php, il n'est maintenant plus n�cessaire de d�finir la constante FPDF_FONTPATH.<BR> -- Le tableau $HTTP_SERVER_VARS n'est plus utilis�. Cela pouvait poser des probl�mes avec les configurations PHP 5 ayant d�sactiv� l'option register_long_arrays.<BR> -- L'incorporation des polices Type1 posait des probl�mes avec certains processeurs de PDF.<BR> -- Le nom du PDF envoy� au navigateur ne pouvait pas comporter d'espace.<BR> -- La m�thode Cell() ne pouvait pas imprimer le nombre 0 (seulement la cha�ne '0').<BR> -</BLOCKQUOTE> -<B>v1.52</B> (30/12/2003) -<BLOCKQUOTE> -- Image() affiche maintenant l'image en 72 dpi si aucune dimension n'est indiqu�e.<BR> -- Output() prend un second param�tre cha�ne pour indiquer la destination.<BR> -- Open() est maintenant appel� automatiquement par AddPage().<BR> -- L'insertion d'image JPEG distante ne g�n�re plus d'erreur.<BR> -- Le s�parateur d�cimal est forc� au point dans le constructeur.<BR> -- Ajout de diff�rents encodages (turc, tha�landais, h�breu, ukrainien et vietnamien).<BR> -- La derni�re ligne d'un MultiCell() cadr� � droite n'�tait pas bien align�e si elle se terminait par un retour-chariot.<BR> -- Plus de message d'erreur sur les en-t�tes d�j� envoy�s lorsque le PDF est g�n�r� sur la sortie standard en mode ligne de commande.<BR> -- Le soulign� allait trop loin lorsque le texte comportait les caract�res \, ( ou ).<BR> -- $HTTP_ENV_VARS a �t� remplac� par $HTTP_SERVER_VARS.<BR> -</BLOCKQUOTE> -<B>v1.51</B> (03/08/2002) -<BLOCKQUOTE> -- Support des polices Type1.<BR> -- Ajout des encodages pour les pays baltes.<BR> -- La classe travaille maintenant en interne en points avec l'origine en bas afin d'�viter deux bugs avec Acrobat 5 :<BR> * L'�paisseur des traits �tait trop importante lors des impressions sous Windows 98 SE et ME.<BR> * Les polices TrueType n'apparaissaient pas imm�diatement dans le plug-in (une police de substitution �tait utilis�e), il fallait provoquer un rafra�chissement de la fen�tre pour les voir appara�tre.<BR> -- La zone cliquable dans une cellule �tait toujours positionn�e � gauche ind�pendamment de l'alignement du texte.<BR> -- Les images JPEG en mode CMYK apparaissaient en couleurs invers�es.<BR> -- Les images PNG transparentes en niveaux de gris ou couleurs vraies �taient incorrectement trait�es.<BR> -- L'ajout de nouvelles polices fonctionne maintenant correctement m�me avec l'option magic_quotes_runtime � on.<BR> -</BLOCKQUOTE> -<B>v1.5</B> (28/05/2002) -<BLOCKQUOTE> -- Support des polices TrueType (AddFont()) et des encodages (Europe de l'Ouest, de l'Est, cyrillique et grec).<BR> -- Ajout de la m�thode Write().<BR> -- Ajout du style soulign�.<BR> -- Support des liens internes et externes (AddLink(), SetLink(), Link()).<BR> -- Gestion de la marge droite et ajout des m�thodes SetRightMargin() et SetTopMargin().<BR> -- Modification de SetDisplayMode() pour s�lectionner un affichage continu ou en colonnes.<BR> -- Le param�tre border de MultiCell() permet de choisir les bords � tracer comme Cell().<BR> -- Lorsqu'un document ne contient aucune page, Close() appelle maintenant AddPage() au lieu de provoquer une erreur fatale.<BR> -</BLOCKQUOTE> -<B>v1.41</B> (13/03/2002) -<BLOCKQUOTE> -- Correction de SetDisplayMode() qui ne fonctionnait plus (le visualiseur PDF utilisait l'affichage par d�faut).<BR> -</BLOCKQUOTE> -<B>v1.4</B> (02/03/2002) -<BLOCKQUOTE> -- PHP3 n'est plus support�.<BR> -- Compression des pages (SetCompression()).<BR> -- Choix du format des pages et possibilit� de changer l'orientation en cours de document.<BR> -- Ajout de la m�thode AcceptPageBreak().<BR> -- Ajout de la m�thode SetLeftMargin().<BR> -- Possibilit� d'imprimer le nombre total de pages (AliasNbPages()).<BR> -- Choix des bords des cellules � tracer.<BR> -- Nouveau mode pour la m�thode Cell() : la position courante se d�place sous la cellule.<BR> -- Possibilit� d'inclure une image en n'indiquant que la hauteur (la largeur est d�termin�e automatiquement).<BR> -- Correction d'un bug : lorsqu'une ligne justifi�e provoquait un saut de page, le pied de page h�ritait de l'espacement inter-mot correspondant.<BR> -</BLOCKQUOTE> -<B>v1.31</B> (12/01/2002) -<BLOCKQUOTE> -- Correction d'un bug dans le trac� du cadre avec MultiCell() : la derni�re ligne partait toujours de la marge gauche.<BR> -- Suppression de l'en-t�te HTTP Expires (pose des probl�mes dans certains cas).<BR> -- Ajout de l'en-t�te HTTP Content-disposition (semble aider dans certains cas).<BR> -</BLOCKQUOTE> -<B>v1.3</B> (03/12/2001) -<BLOCKQUOTE> -- Gestion des sauts de ligne avec justification du texte (MultiCell()).<BR> -- Ajout du support de la couleur (SetDrawColor(), SetFillColor(), SetTextColor()). Possibilit� de dessiner des rectangles pleins et de colorer le fond des cellules.<BR> -- Une cellule dont la largeur est d�clar�e nulle s'�tend jusqu'� la marge droite de la page.<BR> -- L'�paisseur des traits est maintenant conserv�e de page en page et vaut 0,2 mm par d�faut.<BR> -- Ajout de la m�thode SetXY().<BR> -- Correction d'un passage par r�f�rence effectu� d'une mani�re obsol�te en PHP4.<BR> -</BLOCKQUOTE> -<B>v1.2</B> (11/11/2001) -<BLOCKQUOTE> -- Ajout des fichiers de m�trique des polices et de la m�thode GetStringWidth().<BR> -- Possibilit� de centrer et d'aligner � droite le texte dans les cellules.<BR> -- R�glage du mode d'affichage (SetDisplayMode()).<BR> -- Ajout des m�thodes de propri�t� du document (SetAuthor(), SetCreator(), SetKeywords(), SetSubject(), SetTitle()).<BR> -- Possibilit� de forcer le t�l�chargement du PDF.<BR> -- Ajout des m�thodes SetX() et GetX().<BR> -- Lors du saut de page automatique, l'abscisse courante est maintenant conserv�e.<BR> -</BLOCKQUOTE> -<B>v1.11</B> (20/10/2001) -<BLOCKQUOTE> -- L'utilisation des PNG ne n�cessite plus PHP4 et l'extension Zlib. Les donn�es sont int�gr�es directement dans le document PDF sans �tape de d�compression/recompression.<BR> -- L'insertion d'image fonctionne maintenant correctement m�me avec l'option magic_quotes_runtime � on.<BR> -</BLOCKQUOTE> -<B>v1.1</B> (07/10/2001) -<BLOCKQUOTE> -- Support des images JPEG et PNG.<BR> -</BLOCKQUOTE> -<B>v1.01</B> (03/10/2001) -<BLOCKQUOTE> -- Correction d'un bug lors du saut de page : dans le cas o� la m�thode Header() ne sp�cifiait pas de police, celle de la page pr�c�dente n'�tait pas restaur�e et produisait un document incorrect.<BR> -</BLOCKQUOTE> -<B>v1.0</B> (17/09/2001) -<BLOCKQUOTE> -- Premi�re version.<BR> -</BLOCKQUOTE> -</BODY> -</HTML> +<HTML> +<HEAD> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> +<TITLE>Historique</TITLE> +<LINK TYPE="text/css" REL="stylesheet" HREF="fpdf.css"> +</HEAD> +<BODY> +<H2>Historique</H2> +<B>v1.53</B> (31/12/2004) +<BLOCKQUOTE> +- Lorsque le sous-r�pertoire font se trouve dans le m�me r�pertoire que fpdf.php, il n'est maintenant plus n�cessaire de d�finir la constante FPDF_FONTPATH.<BR> +- Le tableau $HTTP_SERVER_VARS n'est plus utilis�. Cela pouvait poser des probl�mes avec les configurations PHP 5 ayant d�sactiv� l'option register_long_arrays.<BR> +- L'incorporation des polices Type1 posait des probl�mes avec certains processeurs de PDF.<BR> +- Le nom du PDF envoy� au navigateur ne pouvait pas comporter d'espace.<BR> +- La m�thode Cell() ne pouvait pas imprimer le nombre 0 (seulement la cha�ne '0').<BR> +</BLOCKQUOTE> +<B>v1.52</B> (30/12/2003) +<BLOCKQUOTE> +- Image() affiche maintenant l'image en 72 dpi si aucune dimension n'est indiqu�e.<BR> +- Output() prend un second param�tre cha�ne pour indiquer la destination.<BR> +- Open() est maintenant appel� automatiquement par AddPage().<BR> +- L'insertion d'image JPEG distante ne g�n�re plus d'erreur.<BR> +- Le s�parateur d�cimal est forc� au point dans le constructeur.<BR> +- Ajout de diff�rents encodages (turc, tha�landais, h�breu, ukrainien et vietnamien).<BR> +- La derni�re ligne d'un MultiCell() cadr� � droite n'�tait pas bien align�e si elle se terminait par un retour-chariot.<BR> +- Plus de message d'erreur sur les en-t�tes d�j� envoy�s lorsque le PDF est g�n�r� sur la sortie standard en mode ligne de commande.<BR> +- Le soulign� allait trop loin lorsque le texte comportait les caract�res \, ( ou ).<BR> +- $HTTP_ENV_VARS a �t� remplac� par $HTTP_SERVER_VARS.<BR> +</BLOCKQUOTE> +<B>v1.51</B> (03/08/2002) +<BLOCKQUOTE> +- Support des polices Type1.<BR> +- Ajout des encodages pour les pays baltes.<BR> +- La classe travaille maintenant en interne en points avec l'origine en bas afin d'�viter deux bugs avec Acrobat 5 :<BR> * L'�paisseur des traits �tait trop importante lors des impressions sous Windows 98 SE et ME.<BR> * Les polices TrueType n'apparaissaient pas imm�diatement dans le plug-in (une police de substitution �tait utilis�e), il fallait provoquer un rafra�chissement de la fen�tre pour les voir appara�tre.<BR> +- La zone cliquable dans une cellule �tait toujours positionn�e � gauche ind�pendamment de l'alignement du texte.<BR> +- Les images JPEG en mode CMYK apparaissaient en couleurs invers�es.<BR> +- Les images PNG transparentes en niveaux de gris ou couleurs vraies �taient incorrectement trait�es.<BR> +- L'ajout de nouvelles polices fonctionne maintenant correctement m�me avec l'option magic_quotes_runtime � on.<BR> +</BLOCKQUOTE> +<B>v1.5</B> (28/05/2002) +<BLOCKQUOTE> +- Support des polices TrueType (AddFont()) et des encodages (Europe de l'Ouest, de l'Est, cyrillique et grec).<BR> +- Ajout de la m�thode Write().<BR> +- Ajout du style soulign�.<BR> +- Support des liens internes et externes (AddLink(), SetLink(), Link()).<BR> +- Gestion de la marge droite et ajout des m�thodes SetRightMargin() et SetTopMargin().<BR> +- Modification de SetDisplayMode() pour s�lectionner un affichage continu ou en colonnes.<BR> +- Le param�tre border de MultiCell() permet de choisir les bords � tracer comme Cell().<BR> +- Lorsqu'un document ne contient aucune page, Close() appelle maintenant AddPage() au lieu de provoquer une erreur fatale.<BR> +</BLOCKQUOTE> +<B>v1.41</B> (13/03/2002) +<BLOCKQUOTE> +- Correction de SetDisplayMode() qui ne fonctionnait plus (le visualiseur PDF utilisait l'affichage par d�faut).<BR> +</BLOCKQUOTE> +<B>v1.4</B> (02/03/2002) +<BLOCKQUOTE> +- PHP3 n'est plus support�.<BR> +- Compression des pages (SetCompression()).<BR> +- Choix du format des pages et possibilit� de changer l'orientation en cours de document.<BR> +- Ajout de la m�thode AcceptPageBreak().<BR> +- Ajout de la m�thode SetLeftMargin().<BR> +- Possibilit� d'imprimer le nombre total de pages (AliasNbPages()).<BR> +- Choix des bords des cellules � tracer.<BR> +- Nouveau mode pour la m�thode Cell() : la position courante se d�place sous la cellule.<BR> +- Possibilit� d'inclure une image en n'indiquant que la hauteur (la largeur est d�termin�e automatiquement).<BR> +- Correction d'un bug : lorsqu'une ligne justifi�e provoquait un saut de page, le pied de page h�ritait de l'espacement inter-mot correspondant.<BR> +</BLOCKQUOTE> +<B>v1.31</B> (12/01/2002) +<BLOCKQUOTE> +- Correction d'un bug dans le trac� du cadre avec MultiCell() : la derni�re ligne partait toujours de la marge gauche.<BR> +- Suppression de l'en-t�te HTTP Expires (pose des probl�mes dans certains cas).<BR> +- Ajout de l'en-t�te HTTP Content-disposition (semble aider dans certains cas).<BR> +</BLOCKQUOTE> +<B>v1.3</B> (03/12/2001) +<BLOCKQUOTE> +- Gestion des sauts de ligne avec justification du texte (MultiCell()).<BR> +- Ajout du support de la couleur (SetDrawColor(), SetFillColor(), SetTextColor()). Possibilit� de dessiner des rectangles pleins et de colorer le fond des cellules.<BR> +- Une cellule dont la largeur est d�clar�e nulle s'�tend jusqu'� la marge droite de la page.<BR> +- L'�paisseur des traits est maintenant conserv�e de page en page et vaut 0,2 mm par d�faut.<BR> +- Ajout de la m�thode SetXY().<BR> +- Correction d'un passage par r�f�rence effectu� d'une mani�re obsol�te en PHP4.<BR> +</BLOCKQUOTE> +<B>v1.2</B> (11/11/2001) +<BLOCKQUOTE> +- Ajout des fichiers de m�trique des polices et de la m�thode GetStringWidth().<BR> +- Possibilit� de centrer et d'aligner � droite le texte dans les cellules.<BR> +- R�glage du mode d'affichage (SetDisplayMode()).<BR> +- Ajout des m�thodes de propri�t� du document (SetAuthor(), SetCreator(), SetKeywords(), SetSubject(), SetTitle()).<BR> +- Possibilit� de forcer le t�l�chargement du PDF.<BR> +- Ajout des m�thodes SetX() et GetX().<BR> +- Lors du saut de page automatique, l'abscisse courante est maintenant conserv�e.<BR> +</BLOCKQUOTE> +<B>v1.11</B> (20/10/2001) +<BLOCKQUOTE> +- L'utilisation des PNG ne n�cessite plus PHP4 et l'extension Zlib. Les donn�es sont int�gr�es directement dans le document PDF sans �tape de d�compression/recompression.<BR> +- L'insertion d'image fonctionne maintenant correctement m�me avec l'option magic_quotes_runtime � on.<BR> +</BLOCKQUOTE> +<B>v1.1</B> (07/10/2001) +<BLOCKQUOTE> +- Support des images JPEG et PNG.<BR> +</BLOCKQUOTE> +<B>v1.01</B> (03/10/2001) +<BLOCKQUOTE> +- Correction d'un bug lors du saut de page : dans le cas o� la m�thode Header() ne sp�cifiait pas de police, celle de la page pr�c�dente n'�tait pas restaur�e et produisait un document incorrect.<BR> +</BLOCKQUOTE> +<B>v1.0</B> (17/09/2001) +<BLOCKQUOTE> +- Premi�re version.<BR> +</BLOCKQUOTE> +</BODY> +</HTML> diff --git a/htdocs/includes/fpdf/fpdf/install.txt b/htdocs/includes/fpdf/fpdf/install.txt index 0e2cfaba92beb58d8fa2e0cdc5126e809c6b0fd7..a2f01fa5e785aba3dfb0bf749d1d4c125d7220c7 100644 --- a/htdocs/includes/fpdf/fpdf/install.txt +++ b/htdocs/includes/fpdf/fpdf/install.txt @@ -1,26 +1,26 @@ -FPDF est constitu� des �l�ments suivants : - -- le fichier principal fpdf.php contenant la classe -- les fichiers de m�trique des polices (contenus dans le r�pertoire font de cette archive) - -Les fichiers de m�trique sont indispensables d�s que l'on veut �crire du texte dans un document. -Ils peuvent se trouver en trois endroits diff�rents : - -- dans le r�pertoire d�fini par la constante FPDF_FONTPATH (si cette constante est d�finie) -- dans le r�pertoire font s'il se trouve au m�me niveau que fpdf.php (comme c'est le cas dans cette archive) -- dans un des r�pertoires accessibles par include() - -Voici un exemple de d�finition de FPDF_FONTPATH (notez le slash final obligatoire) : - -define('FPDF_FONTPATH','/home/www/font/'); -require('fpdf.php'); - -Si ces fichiers ne sont pas accessibles, la m�thode SetFont() produira l'erreur suivante : - -FPDF error: Could not include font metric file - - -Remarques : - -- Seuls les fichiers correspondant aux polices effectivement utilis�es sont n�cessaires -- Les tutoriels fournis dans l'archive sont pr�ts � �tre ex�cut�s +FPDF est constitu� des �l�ments suivants : + +- le fichier principal fpdf.php contenant la classe +- les fichiers de m�trique des polices (contenus dans le r�pertoire font de cette archive) + +Les fichiers de m�trique sont indispensables d�s que l'on veut �crire du texte dans un document. +Ils peuvent se trouver en trois endroits diff�rents : + +- dans le r�pertoire d�fini par la constante FPDF_FONTPATH (si cette constante est d�finie) +- dans le r�pertoire font s'il se trouve au m�me niveau que fpdf.php (comme c'est le cas dans cette archive) +- dans un des r�pertoires accessibles par include() + +Voici un exemple de d�finition de FPDF_FONTPATH (notez le slash final obligatoire) : + +define('FPDF_FONTPATH','/home/www/font/'); +require('fpdf.php'); + +Si ces fichiers ne sont pas accessibles, la m�thode SetFont() produira l'erreur suivante : + +FPDF error: Could not include font metric file + + +Remarques : + +- Seuls les fichiers correspondant aux polices effectivement utilis�es sont n�cessaires +- Les tutoriels fournis dans l'archive sont pr�ts � �tre ex�cut�s diff --git a/htdocs/includes/fpdf/i25/ex.php b/htdocs/includes/fpdf/i25/ex.php index dafc00116aa5f10378f7814db592dcaa5757c68e..07bf9db7bc0ccd8703ce79c1e678984341f12a1e 100755 --- a/htdocs/includes/fpdf/i25/ex.php +++ b/htdocs/includes/fpdf/i25/ex.php @@ -1,9 +1,9 @@ -<?php -define('FPDF_FONTPATH','font/'); -require('i25.php'); - -$pdf=new PDF_i25(); -$pdf->AddPage(); -$pdf->i25(90,40,'12345678'); -$pdf->Output(); -?> +<?php +define('FPDF_FONTPATH','font/'); +require('i25.php'); + +$pdf=new PDF_i25(); +$pdf->AddPage(); +$pdf->i25(90,40,'12345678'); +$pdf->Output(); +?> diff --git a/htdocs/includes/fpdf/i25/info.htm b/htdocs/includes/fpdf/i25/info.htm index 3840769a5204547d94f69cb524b6aa4e4d77edec..7a0c1dafd08b0f9ef51fdce24c0a43586cc33e99 100755 --- a/htdocs/includes/fpdf/i25/info.htm +++ b/htdocs/includes/fpdf/i25/info.htm @@ -1,28 +1,28 @@ -<HTML> -<HEAD> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> -<TITLE>i25 barcodes</TITLE> -<STYLE> -BODY {font-family:"Times New Roman",serif} -H2 {color:#4000A0} -.st {font-weight:bold; color:#900000} -</STYLE> -</HEAD> -<BODY> -<H2>i25 barcodes</H2> -<H4 CLASS="st">Informations</H4>Author: Matthias Lau<BR>License: Freeware -<H4 CLASS="st">Description</H4>This script implements Interleaved 2 of 5 barcodes. An Interleaved 2 of 5 barcode contains -digits (0 to 9) and encodes the data in the width of both bars and spaces. It is used primarily -in the distribution and warehouse industry.<BR> -<BR> -<TT>i25(<B>float</B> xpos, <B>float</B> ypos, <B>string</B> code [, <B>float</B> basewidth [, <B>float</B> height]])</TT><BR> -<BR> -<TT><U>xpos</U></TT>: abscissa of barcode<BR> -<TT><U>ypos</U></TT>: ordinate of barcode<BR> -<TT><U>code</U></TT>: value of barcode<BR> -<TT><U>basewidth</U></TT>: corresponds to the width of a wide bar (defaults to 1)<BR> -<TT><U>height</U></TT>: bar height (defaults to 10)<BR> -<BR> -Note: if the length of the code is not even, a 0 is preprended. -</BODY> -</HTML> +<HTML> +<HEAD> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> +<TITLE>i25 barcodes</TITLE> +<STYLE> +BODY {font-family:"Times New Roman",serif} +H2 {color:#4000A0} +.st {font-weight:bold; color:#900000} +</STYLE> +</HEAD> +<BODY> +<H2>i25 barcodes</H2> +<H4 CLASS="st">Informations</H4>Author: Matthias Lau<BR>License: Freeware +<H4 CLASS="st">Description</H4>This script implements Interleaved 2 of 5 barcodes. An Interleaved 2 of 5 barcode contains +digits (0 to 9) and encodes the data in the width of both bars and spaces. It is used primarily +in the distribution and warehouse industry.<BR> +<BR> +<TT>i25(<B>float</B> xpos, <B>float</B> ypos, <B>string</B> code [, <B>float</B> basewidth [, <B>float</B> height]])</TT><BR> +<BR> +<TT><U>xpos</U></TT>: abscissa of barcode<BR> +<TT><U>ypos</U></TT>: ordinate of barcode<BR> +<TT><U>code</U></TT>: value of barcode<BR> +<TT><U>basewidth</U></TT>: corresponds to the width of a wide bar (defaults to 1)<BR> +<TT><U>height</U></TT>: bar height (defaults to 10)<BR> +<BR> +Note: if the length of the code is not even, a 0 is preprended. +</BODY> +</HTML> diff --git a/htdocs/includes/modules/mailings/README b/htdocs/includes/modules/mailings/README index f0abdae931d4741c5d17d69ffbc79aae88e14185..1bc9de00d37196f08d1fbc009f0f552464e8b872 100644 --- a/htdocs/includes/modules/mailings/README +++ b/htdocs/includes/modules/mailings/README @@ -1,47 +1,47 @@ - -If you want to add your own emails selector/import module. This is steps to follow -to add you own email predefined selector: - - -***** STEP 1 ***** - -Copy file -htdocs/includes/modules/mailings/example.modules.php -into -htdocs/includes/modules/mailings/myselector.modules.php - -You can choose value of your choice instead of "myselector" in name -of new file. - - -***** STEP 2 ***** - -Edit this file myselector.modules.php and change following text: - -"class mailing_example" into "class mailing_myselector" -"var $name='example';" into var $name='myselector'; -"var $desc='...';" into var $desc='A text to describe selector'; -"function mailing_example" into "function mailing_myselector" - -Then add code inside the "add_to_target" function. What you must do is simply -fill the $target PHP array with one record for each email your selector must return. - -You can choose the way you get data: From a file, a database. You are free, -the only requirement is that the $target array is filled by records that are -themselves array of: ('email', 'name', 'firstname'). - -This is for example how you can fill the $target array: - + +If you want to add your own emails selector/import module. This is steps to follow +to add you own email predefined selector: + + +***** STEP 1 ***** + +Copy file +htdocs/includes/modules/mailings/example.modules.php +into +htdocs/includes/modules/mailings/myselector.modules.php + +You can choose value of your choice instead of "myselector" in name +of new file. + + +***** STEP 2 ***** + +Edit this file myselector.modules.php and change following text: + +"class mailing_example" into "class mailing_myselector" +"var $name='example';" into var $name='myselector'; +"var $desc='...';" into var $desc='A text to describe selector'; +"function mailing_example" into "function mailing_myselector" + +Then add code inside the "add_to_target" function. What you must do is simply +fill the $target PHP array with one record for each email your selector must return. + +You can choose the way you get data: From a file, a database. You are free, +the only requirement is that the $target array is filled by records that are +themselves array of: ('email', 'name', 'firstname'). + +This is for example how you can fill the $target array: + // ----- Your code start here ----- $target[0]=array('email'=>'email_0','name'=>'name_0','firstname'=>'firstname_0'); ... $target[n]=array('email'=>'email_n','name'=>'name_n','firstname'=>'firstname_n'); // ----- Your code end here ----- - - - -***** STEP 3 ***** - -Once this file has been edited, you can go to the Dolibarr emailing feature, -you will see a new line selector in the "targets" editor of emailing tool. - + + + +***** STEP 3 ***** + +Once this file has been edited, you can go to the Dolibarr emailing feature, +you will see a new line selector in the "targets" editor of emailing tool. + diff --git a/htdocs/includes/nusoap/.cvsignore b/htdocs/includes/nusoap/.cvsignore index 72012cbe2eb2aef0a04d8684444450ca00168db1..81154dd4d199220e54c82d4a507f05ee8e231c0d 100644 --- a/htdocs/includes/nusoap/.cvsignore +++ b/htdocs/includes/nusoap/.cvsignore @@ -1 +1 @@ -samples +samples diff --git a/htdocs/includes/nusoap/lib/changelog b/htdocs/includes/nusoap/lib/changelog index fe8c5ca59f12020b347720a636b19a3634f9c1f1..b59d38c6d27d782608345ced01e46090fd028377 100644 --- a/htdocs/includes/nusoap/lib/changelog +++ b/htdocs/includes/nusoap/lib/changelog @@ -1,438 +1,438 @@ -2003-07-21, version 0.6.5 -- soap_transport_http: SOAPAction header is quoted again, fixes problem w/ Weblogic Server -- applied Jason Levitt patch for proper array serialization, fixes problem w/ Amazon shopping cart services -- fixed null value serialization -- applied patch from "BZC ToOn'S" - fixes wsdl serialization when no parameters -- applied John's patch, implementing compression for the server - -2003-07-22, version 0.6.5 -- soap_server: fixed bug causing charset encoding not to be passed to the parser -- soap_fault: added default encoding to the fault serialization -- soap_parser: changed the parser to pre-load the parent's result array when processing scalar values. This increases parsing speed. - -2003-07-23, version 0.6.5 -- soap_base: fix code that overwrites user-supplied attributes in serialize_val -- soap_base: use arrays-of-arrays rather than attempting multi-dimensional in serialize_val -- xmlschema: emit import statements and qualify all elements with prefix in serializeSchema (better interop with validation tools) -- soapclient: get xml character encoding from HTTP Content-Type header if provided, e.g. text/xml;charset="UTF-8" -- soapclient: use headers in call if provided (previously ignored this parameter) -- soap_server: in parse_request, if neither getallheaders nor $_SERVER are available, use $HTTP_SERVER_VARS to get SOAPAction and xml encoding - -2003-07-24, version 0.6.5 -- soap_transport_http: apply patch from Steven Brown "if the server closes connection prematurely, nusoap would spin trying to read data that isn't there" - -2003-07-25, version 0.6.5 -- wsdl: apply patch from Sven to workaround single schema limitation -- wsdl: apply a variant of the patch from Holger to handle empty values for array by serializing an array with 0 elements -- xmlschema: remove the redundant default namespace attribute on the schema element; everything in xsd is explicitly specified as being from xsd -- soap_transport_http: fix setCredentials and add TODO comments in sendHTTPS about what to change if this setCredentials stays - -2003-07-30, version 0.6.5 -- nusoap_base: change documentation of soap_defencoding to specify it is the encoding for outgoing messages -- nusoap_base: only change &, <, > to entities, not all HTML entities -- soap_transport_http: update the Content-Type header in sendRequest, since soap_defencoding could be changed after ctor is called -- soap_server: use soap_defencoding instead of charset_encoding -- soap_server: read encoding from _SERVER if available -- nusoap_base: do entity translation for string parameters with an xsd type specified (thanks David Derr) - -2003-07-31, version 0.6.5 -- soap_transport_http: add proxy authentication -- soap_transport_http: build payload the same way for http and https -- wsdl: add proxy authentication -- soapclient: add proxy authentication -- soapclient: allow proxy information in ctor, so that it can be used for wsdl - -2003-08-01, version 0.6.5 -- soap_transport_http: close a persistent connection that's at EOF -- soap_transport_http: prevent conflicts between setEncoding and usePersistentConnection -- soap_transport_http: fix use of $headers instead of $this->incoming_headers in getResponse -- soapclient: improve handling of persistent connections -- soapclient: force xml_encoding to upper case -- soap_server: let the Web server decide whether to close the connection (no Connection: close header) -- soap_server: force xml_encoding to upper case - -2003-08-04, version 0.6.5 -- soap_parser: use XML type information to pick a PHP data type; also decode base64 -- soap_server: read all HTTP headers when using _SERVER or HTTP_SERVER_VARS -- soap_server: add gzip encoding support for outgoing messages -- soap_transport_http: deflate is gzcompress/gzuncompress (cf. http://archive.develooper.com/libwww@perl.org/msg04650.html) -- soap_transport_http: clean use of persistentConnection so it's always a set boolean -- soapclient: add responseData member to access deflated/gunzipped payload - -2003-08-05, version 0.6.5 -- soap_server: look multiple places when setting debug_flag - -2003-08-07, version 0.6.5 -- nusoap_base: serialize specified type (e.g. ArrayOfString) even for simple array -- wsdl: only specify encodingStyle in the input/output soap bindings when it is not empty (thanks Guillaume) - -2003-08-15, version 0.6.5 -- soap_parser: fix parsing of elements with no XSD type specified -- soap_parser: use PHP string type for XSD long and unsignedLong types - -2003-08-16, version 0.6.5 -- soap_parser: fix code generating warning (thanks Torsten) - -2003-08-19, version 0.6.5 -- soap_parser: fix another line of code generating a warning (thanks Torsten) - -2003-08-22, version 0.6.5 -- soap_server: remove all '--' from debug_str; previous code changed '---' to '- --' -- wsdl, soapclient, soap_parser: patch submitted by Mark Spavin as described by - the following... -> Changes for the multiple/nested imports from the wsdl file. This builds an -> array of files not just the last one and also checks for relative paths to -> the parent. This will then get the imported files from the remote site -> instead of your local disk. Local wsdl files should still work (untested). -> -> Changes for multiple encoding sytles as previously posted - -2003-08-24, version 0.6.5 -- wsdl, soapclient: fix some PHP notices from previous update - -2003-08-26, version 0.6.5 -- wsdl: support multiple SOAP ports -- soapclient, soap_server: when no charset is specified, use UTF-8, even though HTTP specifies US-ASCII. -- soap_transport_http: do not prepend $host with 'ssl://' for https (is this required for older cURL versions?) - -2003-08-27, version 0.6.5 -- soap_server: support compressed request messages (thanks John Huong) -- soap_parser: deserialize Apache Vector as an array -- xmlschema: use $this->typemap in getPHPType (which is not used) -- soapclient, wsdl: check for WSDL errors after serializing parameters -- nusoap_base: add serialization of Apache Map (when not using WSDL) -- wsdl: add serialization of Apache Map (when using WSDL) -- wsdl: only change &, <, > to entities, not all HTML entities - -2003-08-28, version 0.6.5 -- soap_transport_http: disable cURL verification of peer and server (formerly the cURL default) -- soap_transport_http: mingle cURL code with straight http, so sendHTTP is no longer needed - -2003-08-29, version 0.6.6 -- soap_transport_http: add setContentType -- soapclient: call setContentType using new getHTTPContentType and getHTTPContentTypeCharset - -2003-09-05, version 0.6.6 -- wsdl: add some more code to handle null/nil values (but there's still a way to go) - -2003-10-21, version 0.6.6 -- soap_transport_http: only include port in Host header if it was specified in the URL -- soap_transport_http: add some code to use OpenSSL for PHP ssl:// scheme, but comment out since it's not ready -- soap_server: use $_SERVER['PHP_SELF'] if $GLOBALS['PHP_SELF'] is not set -- wsdl: add WSDL request and response and transport debug to debug -- wsdl: handle custom type extending xmlschema namespace (GLUE ... Thanks Matt) -- soap_parser: add param to docs -- soapclient: add getHTTPBody, getHTTPContentType, getHTTPContentTypeCharset (anticipating MIME subclass) - -2003-10-28, version 0.6.6 -- nusoap_base: add expandEntities method -- wsdl: use expandEntities -- soap_fault: use expandEntities -- soap_transport_http: Allow credentials to be included in URL, rather than requiring setCredentials -- soap_transport_http: Merge HTTP headers that span multiple lines -- soap_parser: Properly set errors in ctor -- soapclient: Pass headers to parseResponse and parse them in that method - -2003-10-30, version 0.6.6 -- xmlschema: Add some information for the related type to an element - -2003-12-09, version 0.6.6 -- nusoap_base: Add some namespace methods previously in xmlschema -- xmlschema: Improve parsing of complexType, element and simpleType -- xmlschema: Improve serialization -- xmlschema: Track imports -- xmlschema: Track elementFormDefault and form attributes -- wsdl: Support multiple <schema> (note that setting $server->wsdl->schemaTargetNamespace no longer does anything! Use configureWSDL instead.) -- wsdl: Use form attribute of element to control namespace specification -- wsdl: Support chained imports (A imports B which imports C) -- wsdl: Include port in endpoint address when serializing -- soap_server: Fix use of style (rpc|document) and use (encoded|literal) -- soap_server: Support _SERVER[CONTENT_TYPE] in addition to _SERVER[HTTP_CONTENT_TYPE] -- soap_server: Support wsdl with multiple <schema> -- soap_client: Remove a var_dump -- soap_client: Add style and use parameters to call method to support doc/lit without WSDL -- soap_transport_http: Check that $this->fp exists when doing persistent connections - -2003-12-17, version 0.6.6 -- soap_server: pass namespaces to xmlschema constructor -- wsdl: post-process after all imports -- wsdl: remove some debug, add some error handling -- xmlschema: allow enclosing namespaces to be specified in constructor -- xmlschema: improve handling of compositors and simple types - -2004-01-08, version 0.6.6 -- soap_server: when requested WSDL is in a file, return to client using passthru (thanks Ingo Fischer) -- soapclient: have proxy inherit more client state -- soapclient: allow timeout and response timeout to be specified in the constructor -- wsdl: allow timeout and response timeout to be specified in the constructor -- soap_transport_http: allow response timeout to be specified in send and sendHTTPS - -2004-01-28, version 0.6.6 -- wsdl: add namespace for array and scalar when form is qualified -- wsdl: fix a bug in which data type of complexType elements were ignored in serialization -- wsdl: enhance handling of URLs with file scheme -- wsdl: add addSimpleType -- xmlschema: add addSimpleType -- xmlschema: always set phpType elements -- soapclient: allow a wsdl instance to be specified in constructor -- soap_server: allow a wsdl instance to be specified in constructor (not tested!) -- soap_server: fix default SOAPAction created in register method -- soap_transport_http: accept chunking with LF separators in addition to CRLF. -- wsdlcache: added class -- nusoapmime: fix comments - -2004-02-23, version 0.6.6 -- soap_transport_http: don't try to unchunk cURL data, since cURL already does it -- soap_transport_http: append CVS revision to version in User-Agent -- wsdl: serialize boolean as true|false, not 1|0, to agree with XML Schema -- soap_server: always exit() after returning WSDL -- soap_server: use the WSDL URL scheme as the default endpoint URL scheme -- soap_server: append CVS revision to version in X-SOAP-Server -- nusoap_base: add (CVS) revision -- wsdlcache: synchronize using a per-WSDL lock file (Thanks Ingo) -- wsdlcache: add cache lifetime, after which cache contents are invalidated (Thanks Ingo) - -2004-03-15, version 0.6.6 -- nusoap_base: add isArraySimpleOrStruct method -- soap_server: improve WSDL URL scheme determination -- soap_server: only deflate/gzip payloads > 1024 bytes -- soap_server: fix parameter order in fault method (always used as faultcode, faultstring) -- soap_server: refactor parse_request into multiple functions (for sanity) -- soap_server: set the namespace on the Response element to the same as the request -- soap_server: name the return value element 'return' by default -- soap_server: added and documented data fields, so that service programmers can use them if desired -- soap_parser: standardize parsing error message -- soap_parser: fix document and responseHeaders so they are the correct XML text (as documented) -- soap_transport_http: fix read from persistent connection -- soapclient: clean up debugging for persistent connection -- wsdl: enforce correct naming of messages parts when an associative array is used for parameters -- wsdl: better serialization of null values -- wsdl: standardize parsing error message -- xmlschema: standardize parsing error message - -2004-03-24, version 0.6.7 -- soap_transport_http: add digest authentication (based on code by Kevin A. Miller) -- xmlschema: improve parsing of import elements -- wsdl: do schema imports even if there are no wsdl imports - -2004-04-12, version 0.6.7 -- wsdl: serialize multiple elements when maxOccurs="unbounded" and value is an array -- wsdl: serialize soapval values (used to force an XML type, e.g. when WSDL uses an abstract type) -- nusoapmime: do not require nusoap.php (it is now the programmer's responsibility) - -2004-04-21, version 0.6.7 -- soap_parser: parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element) -- soap_server: do not wrap response in a response element for a document style service - -2004-04-30, version 0.6.7 -- soap_transport_http: allow digest auth params to be separated by "," as well as ", " -- soap_transport_http: re-initialize incoming headers for each response -- soap_server: add methodreturnisliteralxml property to allow service function to return XML as a string -- soapclient: improve rpc/literal support -- soapclient: allow XML string as call params in addition to array -- soapclient: support document style and literal encoding when not using WSDL - -2004-05-05, version 0.6.7 -- wsdl: serialize PHP objects for WSDL XML Schema complexTypes, in addition to associative arrays -- wsdl: fix WSDL generation when there is no encodingStyle -- soap_transport_http: suppress fsockopen warnings -- soap_transport_http: detect socket timeouts when reading (0 bytes returned) -- soap_transport_http: read chunked content "in-line" so it works on a persistent connection -- nusoap_base: serialize boolean as true|false, not 1|0, to agree with XML Schema -- nusoap_base: serialize array of struct differently than array of array - -2004-06-25, version 0.6.8 -- soap_server: prefer gzip to deflate, since IE does not like our deflate -- soap_server: move webDescription to the wsdl class -- soap_server: allow class and instance method calls for service (thanks Ingo Fischer and Roland Knall) -- wsdl: get webDescription from the soap_server class -- wsdl: allow compression from the server -- wsdl: fix serialization of soapval without a type -- wsdl: propagate debug value from query string to SOAP endpoint in programmatic WSDL generation -- nusoap_base: add anyType, anySimpleType for 2001 XML Schema -- nusoap_base: provide additional debug functions -- soap_transport_http: ignore Content-Length when chunked encoding is used -- soap_transport_http: remove ':' from username for Basic authentication (cf. RFC 2617) -- soap_transport_http: urldecode username and password taken from URL -- soap_transport_http: use raw inflate/deflate for IE/IIS compatibility, rather than having Zlib headers according to HTTP 1.1 spec -- soap_transport_http: attempt to handle the case when both the service application and Web server compress the response -- soapclient: when creating proxy methods, replace '.' in operation name with '__' in function name -- soapclient: initialize requestHeaders in proxy -- general: use new debug methods; never access debug_str directly - -2004-09-30, version 0.6.8 -- soapclient: do not allow getProxy call when WSDL is not used -- soapclient: use ISO-8859-1 as the charset if not specified in the Content-Type header -- soapclient: when an empty string is specified for the call namespace, do not put the method element in a namespace -- soapclient: let soap_transport_http check for SSL support -- soapclient: have proxy inherit soap_defencoding from the client from which it is generated -- soapclient: do not assume that 'ns1' is an unused namespace prefix; always generate namespace prefixes randomly -- soap_parser: compare any encoding in the XML declaration to the charset from the HTTP Content-Type header (thanks Ingo Fischer) -- soap_parser: improve parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element) -- soap_server: use ISO-8859-1 as the charset if not specified in the Content-Type header -- soap_server: allow suppression of automatic UTF-8 decoding -- soap_server: fix a bug when call_user_func_array() is used -- soap_transport_http: correct digest authentication through a proxy -- wsdl: serialize SOAP-ENC types similarly to XSD types -- xmlschema: force unprefixed type into default namespace -- xmlschema: fix serialization of definition of simple types - -2004-10-01, version 0.6.8 -- soap_parser: handle default namespace attributes -- soap_server: add default_utf8 field -- soap_server: support literal encoding (with RPC style) -- soap_transport_http: parse HTTP status and generate error for 300, 302-307, 400, 401-417, 501-505 (thanks for the idea Ghislain) -- soap_transport_http: follow HTTP redirection (HTTP status 301 and Location header) (thanks for the idea Ghislain) -- xmlschema: allow any attributes to be specified in an element of a complexType, e.g., abstract, default, form, minOccurs, maxOccurs, nillable (thanks Jirka Pech for the original patch) - -2004-10-02, version 0.6.8 -- soapclient: read/write cookies (thanks Ingo) -- soap_server: change faultcode on non-resendable faults to Client -- soap_transport_http: read/write cookies (thanks Ingo) - -2004-10-05, version 0.6.8 -- wsdl: add addElement method -- wsdl: support the document style in the register method -- xmlschema: parse unnamed simpleTypes, rather than ignoring them -- xmlschema: include untyped elements when parsing a complexType -- xmlschema: add addElement method - -2004-10-14, version 0.6.8 -- soapclient: support client certificates -- soap_parser: deserialize attributes, prefixing names with "!" -- soap_server: notify the client with HTML when WSDL is requested but not supported by service -- soap_transport_http: support client certificates -- wsdl: support defaults for elements of a complexType -- wsdl: serialize elements from complexType extension base -- wsdl: serialize data (associative array elements) as attributes according to XML Schema -- xmlschema: record extension base if present for a complexType - -2004-12-15, version 0.6.8 -- nusoap_base: add 2000 XML Schema (rare, but used by Akamai) -- soap_parser: avoid deserializing more common attributes that are not data -- soap_parser: be lax when HTTP specifies ISO-8859-1 (the default) and XML specifies UTF-8 (the norm) -- soap_server: account for the fact that get_class_methods returns methods in all lower case (thanks Steve Haldane) -- soap_transport_http: parse digest info that includes '=' in the data (thanks Jinsuk Kim) -- wsdl: feably handle some cases for literal serialization of form="unqualified" elements -- wsdl: don't serialize the decimal portion of a PHP double when the XML type is long -- wsdl: fix serialization of attributes for complexType that is an extension -- wsdlcache: enhance diagnostics -- xmlschema: handle untyped elements -- xmlschema: handle WSDL for SOAP Array that uses the base attribute plus a sequence of element - -2005-01-22, version 0.6.8 -- wsdl: allow an element in one schema to have a type from another schema - -2005-01-24, version 0.6.8 -- xmlschema: correctly parse nested complexType definitions - -2005-02-14, version 0.6.8 -- nusoap_base: fix a bug in which attributes were sometimes not serialized with a value -- nusoap_base: improve serialization of null values (thanks Dominique Stender) -- soap_parser: parse null values by handling the nil attribute (thanks Dominique Stender) -- soap_server: set character encoding for a fault to be the same as for the server (thanks Mark Scott) -- soap_server: correctly check for null value returned from method when WSDL is used (without WSDL, cannot distinguish whether NULL or void return is desired) -- soapclient: for document style, call should always return an array rooted at the response part (all bets are off when there are multiple parts) -- xmlschema: save enumeration values parsed from WSDL - -2005-02-10, version 0.6.9 -- soapclient: only set SOAP headers when they are specified in call params (so setHeaders still works) - -2005-04-04, version 0.6.9 -- soap_server: use get_class instead of is_a (thanks Thomas Noel) -- soapclient: use get_class instead of is_a (thanks Thomas Noel) -- soapclient: add setEndpoint method -- soap_transport_http: fix client certificates (thanks Doug Anarino and Eryan Eriobowo) - -2005-04-29, version 0.6.9 -- nusoap_base: add global variable and methods for setting debug level -- nusoap_base: use xsd:anyType instead of xsd:ur-type to serialize arrays with multiple element types (thanks Ingo Fischer) -- nusoap_base: expand entities in attributes (thanks Gaetano Giunta) -- soapclient: call parent constructor -- soapval: call parent constructor -- soap_fault: call parent constructor -- soap_parser: call parent constructor -- soap_server: assume get_class_methods always returns lower case for PHP 4.x only -- soap_server: call parent constructor -- soap_transport_http: do nothing in setEncoding if gzdeflate is not present (thanks Franck Touanen for pointing this out) -- soap_transport_http: fix check for server request for digest authentication (thanks Mark Spavin) -- soap_transport_http: call parent constructor -- wsdl: fix documentation page popup of one method after another (thanks Owen) -- wsdl: call parent constructor -- wsdl: expand entities in attributes (thanks Gaetano Giunta) -- xmlschema: call parent constructor - -2005-06-03, version 0.6.9 -- nusoap_base: serialize empty arrays as having elements xsd:anyType[0] -- nusoap_base: add encodingStyle parameter to serializeEnvelope -- nusoap_base: serialize xsi:type with nil values -- nusoap_base: improve debug and comments -- soap_parser: correctly parse an empty array to an empty array, not an empty string -- soap_parser: improve debug and comments -- soap_server: specify encodingStyle for envelope when WSDL is used -- soapclient: factor out new getProxyClassCode method -- soapclient: specify encodingStyle for envelope -- soapclient: improve debug and comments -- wsdl: add namespace for Apache SOAP types if a variable of such type is serialized -- wsdl: serialize nil value for nillable elements when no value is provided -- wsdl: serialize xsi:type with nil values -- wsdl: copy attributes as well as elements to an element from its complexType -- wsdl: specify encodingStyle for operations -- wsdl: improve debug and comments -- xmlschema: improve debug and comments - -2005-06-03, version 0.7.0 -- nusoap_base: improve debug and comments -- nusoap_base: fix version, which should have been 0.7.0 since 2005-03-04 - -2005-06-06, version 0.7.1 -- nusoap_base: adjust numeric element names for serialization, instead of forcing them to 'soapVal' -- nusoapmime: add type=text/xml to multipart/related (thanks Emmanuel Cordonnier) -- soap_fault: fix serialization of detail -- soap_server: check required parameters for register method -- soap_server: when getallheaders is used, massage header names -- soap_server: use SOAPAction to determine operation when doc/lit service does not wrap parameters in an element with the method name (thanks Peter Hrastnik) -- soap_transport_http: correctly handle multiple HTTP/1.1 100 responses for https (thanks Jan Slabon) -- wsdl: fixed documentation for addComplexType (thanks Csintalan �d�m) -- wsdl: serialize array data when maxOccurs = 'unbounded' OR maxOccurs > 1 (thanks Dominique Schreckling) -- wsdl: when serializing a string == 'false' as a boolean, set the value to false -- wsdl: when serializing a complexType, require the PHP value supplied to be an array - -2005-07-01, version 0.7.1 -- nusoap_base: Allow SOAP headers to be supplied as an array like parameters -- soap_parser: de-serialize simpleContent that accompanies complexContent -- soap_server: append debug information when programmatically-defined WSDL is returned -- soap_transport_http: Add debug when an outgoing header is set -- soapclient: Allow SOAP headers to be supplied as an array like parameters -- xmlschema: serialize attributes more generally, rather than assuming they are for SOAP 1.1 Array -- wsdl: when serializing, look up types by namespace, not prefix (simple programmatic doc/lit WSDL now seems to work) -- wsdl: process namespace declarations first when parsing an element - -2005-07-27, version 0.7.1 -- nusoap_base: do not override supplied element name with class name when serializing an object in serialize_val -- nusoap_base: remove http://soapinterop.org/xsd (si) from namespaces array -- nusoapmime: add nusoapservermime class to implement MIME attachments on the server -- soap_fault: improve documentation -- soap_server: improve documentation -- soap_server: make consistent use of _SERVER and HTTP_SERVER_VARS -- soap_server: make all incoming HTTP header keys lower case -- soap_server: add hook functions to support subclassing for MIME attachments -- soap_transport_http: remove an unnecessary global statement -- soapclient: when creating a proxy, make $params within each function an associative array -- soapval: improve documentation -- wsdl: when serializing complexType elements, used typed serialization if there is either a type or a reference for the element -- wsdl: allow PHP objects to be serialized as SOAP structs in serializeType -- wsdl: for WSDL and XML Schema imports, don't forget to use the TCP port number (thanks Luca GIOPPO) -- wsdl: make consistent use of _SERVER and HTTP_SERVER_VARS -- xmlschema: improve documentation - -2005-07-31, version 0.7.2 -- nusoap_base: correctly serialize attributes in serialize_val (thanks Hidran Arias) -- soap_parser: when resolving references, do not assume that buildVal returns an array (thanks Akshell) -- soap_parser: removed decode_entities, which does not work (thanks Martin Sarsale) -- soap_server: fix a bug parsing headers from _SERVER and HTTP_SERVER_VARS (thanks Bert Catsburg) -- soap_server: parse all "headers" from HTTP_SERVER_VARS (not just HTTP_*) -- soap_server: use PHP_SELF instead of SCRIPT_NAME for WSDL endpoint -- soap_server: when generating a fault while debug_flag is true, put debug into faultdetail -- wsdl: add enumeration parameter to addSimpleType -- xmlschema: add enumeration parameter to addSimpleType +2003-07-21, version 0.6.5 +- soap_transport_http: SOAPAction header is quoted again, fixes problem w/ Weblogic Server +- applied Jason Levitt patch for proper array serialization, fixes problem w/ Amazon shopping cart services +- fixed null value serialization +- applied patch from "BZC ToOn'S" - fixes wsdl serialization when no parameters +- applied John's patch, implementing compression for the server + +2003-07-22, version 0.6.5 +- soap_server: fixed bug causing charset encoding not to be passed to the parser +- soap_fault: added default encoding to the fault serialization +- soap_parser: changed the parser to pre-load the parent's result array when processing scalar values. This increases parsing speed. + +2003-07-23, version 0.6.5 +- soap_base: fix code that overwrites user-supplied attributes in serialize_val +- soap_base: use arrays-of-arrays rather than attempting multi-dimensional in serialize_val +- xmlschema: emit import statements and qualify all elements with prefix in serializeSchema (better interop with validation tools) +- soapclient: get xml character encoding from HTTP Content-Type header if provided, e.g. text/xml;charset="UTF-8" +- soapclient: use headers in call if provided (previously ignored this parameter) +- soap_server: in parse_request, if neither getallheaders nor $_SERVER are available, use $HTTP_SERVER_VARS to get SOAPAction and xml encoding + +2003-07-24, version 0.6.5 +- soap_transport_http: apply patch from Steven Brown "if the server closes connection prematurely, nusoap would spin trying to read data that isn't there" + +2003-07-25, version 0.6.5 +- wsdl: apply patch from Sven to workaround single schema limitation +- wsdl: apply a variant of the patch from Holger to handle empty values for array by serializing an array with 0 elements +- xmlschema: remove the redundant default namespace attribute on the schema element; everything in xsd is explicitly specified as being from xsd +- soap_transport_http: fix setCredentials and add TODO comments in sendHTTPS about what to change if this setCredentials stays + +2003-07-30, version 0.6.5 +- nusoap_base: change documentation of soap_defencoding to specify it is the encoding for outgoing messages +- nusoap_base: only change &, <, > to entities, not all HTML entities +- soap_transport_http: update the Content-Type header in sendRequest, since soap_defencoding could be changed after ctor is called +- soap_server: use soap_defencoding instead of charset_encoding +- soap_server: read encoding from _SERVER if available +- nusoap_base: do entity translation for string parameters with an xsd type specified (thanks David Derr) + +2003-07-31, version 0.6.5 +- soap_transport_http: add proxy authentication +- soap_transport_http: build payload the same way for http and https +- wsdl: add proxy authentication +- soapclient: add proxy authentication +- soapclient: allow proxy information in ctor, so that it can be used for wsdl + +2003-08-01, version 0.6.5 +- soap_transport_http: close a persistent connection that's at EOF +- soap_transport_http: prevent conflicts between setEncoding and usePersistentConnection +- soap_transport_http: fix use of $headers instead of $this->incoming_headers in getResponse +- soapclient: improve handling of persistent connections +- soapclient: force xml_encoding to upper case +- soap_server: let the Web server decide whether to close the connection (no Connection: close header) +- soap_server: force xml_encoding to upper case + +2003-08-04, version 0.6.5 +- soap_parser: use XML type information to pick a PHP data type; also decode base64 +- soap_server: read all HTTP headers when using _SERVER or HTTP_SERVER_VARS +- soap_server: add gzip encoding support for outgoing messages +- soap_transport_http: deflate is gzcompress/gzuncompress (cf. http://archive.develooper.com/libwww@perl.org/msg04650.html) +- soap_transport_http: clean use of persistentConnection so it's always a set boolean +- soapclient: add responseData member to access deflated/gunzipped payload + +2003-08-05, version 0.6.5 +- soap_server: look multiple places when setting debug_flag + +2003-08-07, version 0.6.5 +- nusoap_base: serialize specified type (e.g. ArrayOfString) even for simple array +- wsdl: only specify encodingStyle in the input/output soap bindings when it is not empty (thanks Guillaume) + +2003-08-15, version 0.6.5 +- soap_parser: fix parsing of elements with no XSD type specified +- soap_parser: use PHP string type for XSD long and unsignedLong types + +2003-08-16, version 0.6.5 +- soap_parser: fix code generating warning (thanks Torsten) + +2003-08-19, version 0.6.5 +- soap_parser: fix another line of code generating a warning (thanks Torsten) + +2003-08-22, version 0.6.5 +- soap_server: remove all '--' from debug_str; previous code changed '---' to '- --' +- wsdl, soapclient, soap_parser: patch submitted by Mark Spavin as described by + the following... +> Changes for the multiple/nested imports from the wsdl file. This builds an +> array of files not just the last one and also checks for relative paths to +> the parent. This will then get the imported files from the remote site +> instead of your local disk. Local wsdl files should still work (untested). +> +> Changes for multiple encoding sytles as previously posted + +2003-08-24, version 0.6.5 +- wsdl, soapclient: fix some PHP notices from previous update + +2003-08-26, version 0.6.5 +- wsdl: support multiple SOAP ports +- soapclient, soap_server: when no charset is specified, use UTF-8, even though HTTP specifies US-ASCII. +- soap_transport_http: do not prepend $host with 'ssl://' for https (is this required for older cURL versions?) + +2003-08-27, version 0.6.5 +- soap_server: support compressed request messages (thanks John Huong) +- soap_parser: deserialize Apache Vector as an array +- xmlschema: use $this->typemap in getPHPType (which is not used) +- soapclient, wsdl: check for WSDL errors after serializing parameters +- nusoap_base: add serialization of Apache Map (when not using WSDL) +- wsdl: add serialization of Apache Map (when using WSDL) +- wsdl: only change &, <, > to entities, not all HTML entities + +2003-08-28, version 0.6.5 +- soap_transport_http: disable cURL verification of peer and server (formerly the cURL default) +- soap_transport_http: mingle cURL code with straight http, so sendHTTP is no longer needed + +2003-08-29, version 0.6.6 +- soap_transport_http: add setContentType +- soapclient: call setContentType using new getHTTPContentType and getHTTPContentTypeCharset + +2003-09-05, version 0.6.6 +- wsdl: add some more code to handle null/nil values (but there's still a way to go) + +2003-10-21, version 0.6.6 +- soap_transport_http: only include port in Host header if it was specified in the URL +- soap_transport_http: add some code to use OpenSSL for PHP ssl:// scheme, but comment out since it's not ready +- soap_server: use $_SERVER['PHP_SELF'] if $GLOBALS['PHP_SELF'] is not set +- wsdl: add WSDL request and response and transport debug to debug +- wsdl: handle custom type extending xmlschema namespace (GLUE ... Thanks Matt) +- soap_parser: add param to docs +- soapclient: add getHTTPBody, getHTTPContentType, getHTTPContentTypeCharset (anticipating MIME subclass) + +2003-10-28, version 0.6.6 +- nusoap_base: add expandEntities method +- wsdl: use expandEntities +- soap_fault: use expandEntities +- soap_transport_http: Allow credentials to be included in URL, rather than requiring setCredentials +- soap_transport_http: Merge HTTP headers that span multiple lines +- soap_parser: Properly set errors in ctor +- soapclient: Pass headers to parseResponse and parse them in that method + +2003-10-30, version 0.6.6 +- xmlschema: Add some information for the related type to an element + +2003-12-09, version 0.6.6 +- nusoap_base: Add some namespace methods previously in xmlschema +- xmlschema: Improve parsing of complexType, element and simpleType +- xmlschema: Improve serialization +- xmlschema: Track imports +- xmlschema: Track elementFormDefault and form attributes +- wsdl: Support multiple <schema> (note that setting $server->wsdl->schemaTargetNamespace no longer does anything! Use configureWSDL instead.) +- wsdl: Use form attribute of element to control namespace specification +- wsdl: Support chained imports (A imports B which imports C) +- wsdl: Include port in endpoint address when serializing +- soap_server: Fix use of style (rpc|document) and use (encoded|literal) +- soap_server: Support _SERVER[CONTENT_TYPE] in addition to _SERVER[HTTP_CONTENT_TYPE] +- soap_server: Support wsdl with multiple <schema> +- soap_client: Remove a var_dump +- soap_client: Add style and use parameters to call method to support doc/lit without WSDL +- soap_transport_http: Check that $this->fp exists when doing persistent connections + +2003-12-17, version 0.6.6 +- soap_server: pass namespaces to xmlschema constructor +- wsdl: post-process after all imports +- wsdl: remove some debug, add some error handling +- xmlschema: allow enclosing namespaces to be specified in constructor +- xmlschema: improve handling of compositors and simple types + +2004-01-08, version 0.6.6 +- soap_server: when requested WSDL is in a file, return to client using passthru (thanks Ingo Fischer) +- soapclient: have proxy inherit more client state +- soapclient: allow timeout and response timeout to be specified in the constructor +- wsdl: allow timeout and response timeout to be specified in the constructor +- soap_transport_http: allow response timeout to be specified in send and sendHTTPS + +2004-01-28, version 0.6.6 +- wsdl: add namespace for array and scalar when form is qualified +- wsdl: fix a bug in which data type of complexType elements were ignored in serialization +- wsdl: enhance handling of URLs with file scheme +- wsdl: add addSimpleType +- xmlschema: add addSimpleType +- xmlschema: always set phpType elements +- soapclient: allow a wsdl instance to be specified in constructor +- soap_server: allow a wsdl instance to be specified in constructor (not tested!) +- soap_server: fix default SOAPAction created in register method +- soap_transport_http: accept chunking with LF separators in addition to CRLF. +- wsdlcache: added class +- nusoapmime: fix comments + +2004-02-23, version 0.6.6 +- soap_transport_http: don't try to unchunk cURL data, since cURL already does it +- soap_transport_http: append CVS revision to version in User-Agent +- wsdl: serialize boolean as true|false, not 1|0, to agree with XML Schema +- soap_server: always exit() after returning WSDL +- soap_server: use the WSDL URL scheme as the default endpoint URL scheme +- soap_server: append CVS revision to version in X-SOAP-Server +- nusoap_base: add (CVS) revision +- wsdlcache: synchronize using a per-WSDL lock file (Thanks Ingo) +- wsdlcache: add cache lifetime, after which cache contents are invalidated (Thanks Ingo) + +2004-03-15, version 0.6.6 +- nusoap_base: add isArraySimpleOrStruct method +- soap_server: improve WSDL URL scheme determination +- soap_server: only deflate/gzip payloads > 1024 bytes +- soap_server: fix parameter order in fault method (always used as faultcode, faultstring) +- soap_server: refactor parse_request into multiple functions (for sanity) +- soap_server: set the namespace on the Response element to the same as the request +- soap_server: name the return value element 'return' by default +- soap_server: added and documented data fields, so that service programmers can use them if desired +- soap_parser: standardize parsing error message +- soap_parser: fix document and responseHeaders so they are the correct XML text (as documented) +- soap_transport_http: fix read from persistent connection +- soapclient: clean up debugging for persistent connection +- wsdl: enforce correct naming of messages parts when an associative array is used for parameters +- wsdl: better serialization of null values +- wsdl: standardize parsing error message +- xmlschema: standardize parsing error message + +2004-03-24, version 0.6.7 +- soap_transport_http: add digest authentication (based on code by Kevin A. Miller) +- xmlschema: improve parsing of import elements +- wsdl: do schema imports even if there are no wsdl imports + +2004-04-12, version 0.6.7 +- wsdl: serialize multiple elements when maxOccurs="unbounded" and value is an array +- wsdl: serialize soapval values (used to force an XML type, e.g. when WSDL uses an abstract type) +- nusoapmime: do not require nusoap.php (it is now the programmer's responsibility) + +2004-04-21, version 0.6.7 +- soap_parser: parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element) +- soap_server: do not wrap response in a response element for a document style service + +2004-04-30, version 0.6.7 +- soap_transport_http: allow digest auth params to be separated by "," as well as ", " +- soap_transport_http: re-initialize incoming headers for each response +- soap_server: add methodreturnisliteralxml property to allow service function to return XML as a string +- soapclient: improve rpc/literal support +- soapclient: allow XML string as call params in addition to array +- soapclient: support document style and literal encoding when not using WSDL + +2004-05-05, version 0.6.7 +- wsdl: serialize PHP objects for WSDL XML Schema complexTypes, in addition to associative arrays +- wsdl: fix WSDL generation when there is no encodingStyle +- soap_transport_http: suppress fsockopen warnings +- soap_transport_http: detect socket timeouts when reading (0 bytes returned) +- soap_transport_http: read chunked content "in-line" so it works on a persistent connection +- nusoap_base: serialize boolean as true|false, not 1|0, to agree with XML Schema +- nusoap_base: serialize array of struct differently than array of array + +2004-06-25, version 0.6.8 +- soap_server: prefer gzip to deflate, since IE does not like our deflate +- soap_server: move webDescription to the wsdl class +- soap_server: allow class and instance method calls for service (thanks Ingo Fischer and Roland Knall) +- wsdl: get webDescription from the soap_server class +- wsdl: allow compression from the server +- wsdl: fix serialization of soapval without a type +- wsdl: propagate debug value from query string to SOAP endpoint in programmatic WSDL generation +- nusoap_base: add anyType, anySimpleType for 2001 XML Schema +- nusoap_base: provide additional debug functions +- soap_transport_http: ignore Content-Length when chunked encoding is used +- soap_transport_http: remove ':' from username for Basic authentication (cf. RFC 2617) +- soap_transport_http: urldecode username and password taken from URL +- soap_transport_http: use raw inflate/deflate for IE/IIS compatibility, rather than having Zlib headers according to HTTP 1.1 spec +- soap_transport_http: attempt to handle the case when both the service application and Web server compress the response +- soapclient: when creating proxy methods, replace '.' in operation name with '__' in function name +- soapclient: initialize requestHeaders in proxy +- general: use new debug methods; never access debug_str directly + +2004-09-30, version 0.6.8 +- soapclient: do not allow getProxy call when WSDL is not used +- soapclient: use ISO-8859-1 as the charset if not specified in the Content-Type header +- soapclient: when an empty string is specified for the call namespace, do not put the method element in a namespace +- soapclient: let soap_transport_http check for SSL support +- soapclient: have proxy inherit soap_defencoding from the client from which it is generated +- soapclient: do not assume that 'ns1' is an unused namespace prefix; always generate namespace prefixes randomly +- soap_parser: compare any encoding in the XML declaration to the charset from the HTTP Content-Type header (thanks Ingo Fischer) +- soap_parser: improve parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element) +- soap_server: use ISO-8859-1 as the charset if not specified in the Content-Type header +- soap_server: allow suppression of automatic UTF-8 decoding +- soap_server: fix a bug when call_user_func_array() is used +- soap_transport_http: correct digest authentication through a proxy +- wsdl: serialize SOAP-ENC types similarly to XSD types +- xmlschema: force unprefixed type into default namespace +- xmlschema: fix serialization of definition of simple types + +2004-10-01, version 0.6.8 +- soap_parser: handle default namespace attributes +- soap_server: add default_utf8 field +- soap_server: support literal encoding (with RPC style) +- soap_transport_http: parse HTTP status and generate error for 300, 302-307, 400, 401-417, 501-505 (thanks for the idea Ghislain) +- soap_transport_http: follow HTTP redirection (HTTP status 301 and Location header) (thanks for the idea Ghislain) +- xmlschema: allow any attributes to be specified in an element of a complexType, e.g., abstract, default, form, minOccurs, maxOccurs, nillable (thanks Jirka Pech for the original patch) + +2004-10-02, version 0.6.8 +- soapclient: read/write cookies (thanks Ingo) +- soap_server: change faultcode on non-resendable faults to Client +- soap_transport_http: read/write cookies (thanks Ingo) + +2004-10-05, version 0.6.8 +- wsdl: add addElement method +- wsdl: support the document style in the register method +- xmlschema: parse unnamed simpleTypes, rather than ignoring them +- xmlschema: include untyped elements when parsing a complexType +- xmlschema: add addElement method + +2004-10-14, version 0.6.8 +- soapclient: support client certificates +- soap_parser: deserialize attributes, prefixing names with "!" +- soap_server: notify the client with HTML when WSDL is requested but not supported by service +- soap_transport_http: support client certificates +- wsdl: support defaults for elements of a complexType +- wsdl: serialize elements from complexType extension base +- wsdl: serialize data (associative array elements) as attributes according to XML Schema +- xmlschema: record extension base if present for a complexType + +2004-12-15, version 0.6.8 +- nusoap_base: add 2000 XML Schema (rare, but used by Akamai) +- soap_parser: avoid deserializing more common attributes that are not data +- soap_parser: be lax when HTTP specifies ISO-8859-1 (the default) and XML specifies UTF-8 (the norm) +- soap_server: account for the fact that get_class_methods returns methods in all lower case (thanks Steve Haldane) +- soap_transport_http: parse digest info that includes '=' in the data (thanks Jinsuk Kim) +- wsdl: feably handle some cases for literal serialization of form="unqualified" elements +- wsdl: don't serialize the decimal portion of a PHP double when the XML type is long +- wsdl: fix serialization of attributes for complexType that is an extension +- wsdlcache: enhance diagnostics +- xmlschema: handle untyped elements +- xmlschema: handle WSDL for SOAP Array that uses the base attribute plus a sequence of element + +2005-01-22, version 0.6.8 +- wsdl: allow an element in one schema to have a type from another schema + +2005-01-24, version 0.6.8 +- xmlschema: correctly parse nested complexType definitions + +2005-02-14, version 0.6.8 +- nusoap_base: fix a bug in which attributes were sometimes not serialized with a value +- nusoap_base: improve serialization of null values (thanks Dominique Stender) +- soap_parser: parse null values by handling the nil attribute (thanks Dominique Stender) +- soap_server: set character encoding for a fault to be the same as for the server (thanks Mark Scott) +- soap_server: correctly check for null value returned from method when WSDL is used (without WSDL, cannot distinguish whether NULL or void return is desired) +- soapclient: for document style, call should always return an array rooted at the response part (all bets are off when there are multiple parts) +- xmlschema: save enumeration values parsed from WSDL + +2005-02-10, version 0.6.9 +- soapclient: only set SOAP headers when they are specified in call params (so setHeaders still works) + +2005-04-04, version 0.6.9 +- soap_server: use get_class instead of is_a (thanks Thomas Noel) +- soapclient: use get_class instead of is_a (thanks Thomas Noel) +- soapclient: add setEndpoint method +- soap_transport_http: fix client certificates (thanks Doug Anarino and Eryan Eriobowo) + +2005-04-29, version 0.6.9 +- nusoap_base: add global variable and methods for setting debug level +- nusoap_base: use xsd:anyType instead of xsd:ur-type to serialize arrays with multiple element types (thanks Ingo Fischer) +- nusoap_base: expand entities in attributes (thanks Gaetano Giunta) +- soapclient: call parent constructor +- soapval: call parent constructor +- soap_fault: call parent constructor +- soap_parser: call parent constructor +- soap_server: assume get_class_methods always returns lower case for PHP 4.x only +- soap_server: call parent constructor +- soap_transport_http: do nothing in setEncoding if gzdeflate is not present (thanks Franck Touanen for pointing this out) +- soap_transport_http: fix check for server request for digest authentication (thanks Mark Spavin) +- soap_transport_http: call parent constructor +- wsdl: fix documentation page popup of one method after another (thanks Owen) +- wsdl: call parent constructor +- wsdl: expand entities in attributes (thanks Gaetano Giunta) +- xmlschema: call parent constructor + +2005-06-03, version 0.6.9 +- nusoap_base: serialize empty arrays as having elements xsd:anyType[0] +- nusoap_base: add encodingStyle parameter to serializeEnvelope +- nusoap_base: serialize xsi:type with nil values +- nusoap_base: improve debug and comments +- soap_parser: correctly parse an empty array to an empty array, not an empty string +- soap_parser: improve debug and comments +- soap_server: specify encodingStyle for envelope when WSDL is used +- soapclient: factor out new getProxyClassCode method +- soapclient: specify encodingStyle for envelope +- soapclient: improve debug and comments +- wsdl: add namespace for Apache SOAP types if a variable of such type is serialized +- wsdl: serialize nil value for nillable elements when no value is provided +- wsdl: serialize xsi:type with nil values +- wsdl: copy attributes as well as elements to an element from its complexType +- wsdl: specify encodingStyle for operations +- wsdl: improve debug and comments +- xmlschema: improve debug and comments + +2005-06-03, version 0.7.0 +- nusoap_base: improve debug and comments +- nusoap_base: fix version, which should have been 0.7.0 since 2005-03-04 + +2005-06-06, version 0.7.1 +- nusoap_base: adjust numeric element names for serialization, instead of forcing them to 'soapVal' +- nusoapmime: add type=text/xml to multipart/related (thanks Emmanuel Cordonnier) +- soap_fault: fix serialization of detail +- soap_server: check required parameters for register method +- soap_server: when getallheaders is used, massage header names +- soap_server: use SOAPAction to determine operation when doc/lit service does not wrap parameters in an element with the method name (thanks Peter Hrastnik) +- soap_transport_http: correctly handle multiple HTTP/1.1 100 responses for https (thanks Jan Slabon) +- wsdl: fixed documentation for addComplexType (thanks Csintalan �d�m) +- wsdl: serialize array data when maxOccurs = 'unbounded' OR maxOccurs > 1 (thanks Dominique Schreckling) +- wsdl: when serializing a string == 'false' as a boolean, set the value to false +- wsdl: when serializing a complexType, require the PHP value supplied to be an array + +2005-07-01, version 0.7.1 +- nusoap_base: Allow SOAP headers to be supplied as an array like parameters +- soap_parser: de-serialize simpleContent that accompanies complexContent +- soap_server: append debug information when programmatically-defined WSDL is returned +- soap_transport_http: Add debug when an outgoing header is set +- soapclient: Allow SOAP headers to be supplied as an array like parameters +- xmlschema: serialize attributes more generally, rather than assuming they are for SOAP 1.1 Array +- wsdl: when serializing, look up types by namespace, not prefix (simple programmatic doc/lit WSDL now seems to work) +- wsdl: process namespace declarations first when parsing an element + +2005-07-27, version 0.7.1 +- nusoap_base: do not override supplied element name with class name when serializing an object in serialize_val +- nusoap_base: remove http://soapinterop.org/xsd (si) from namespaces array +- nusoapmime: add nusoapservermime class to implement MIME attachments on the server +- soap_fault: improve documentation +- soap_server: improve documentation +- soap_server: make consistent use of _SERVER and HTTP_SERVER_VARS +- soap_server: make all incoming HTTP header keys lower case +- soap_server: add hook functions to support subclassing for MIME attachments +- soap_transport_http: remove an unnecessary global statement +- soapclient: when creating a proxy, make $params within each function an associative array +- soapval: improve documentation +- wsdl: when serializing complexType elements, used typed serialization if there is either a type or a reference for the element +- wsdl: allow PHP objects to be serialized as SOAP structs in serializeType +- wsdl: for WSDL and XML Schema imports, don't forget to use the TCP port number (thanks Luca GIOPPO) +- wsdl: make consistent use of _SERVER and HTTP_SERVER_VARS +- xmlschema: improve documentation + +2005-07-31, version 0.7.2 +- nusoap_base: correctly serialize attributes in serialize_val (thanks Hidran Arias) +- soap_parser: when resolving references, do not assume that buildVal returns an array (thanks Akshell) +- soap_parser: removed decode_entities, which does not work (thanks Martin Sarsale) +- soap_server: fix a bug parsing headers from _SERVER and HTTP_SERVER_VARS (thanks Bert Catsburg) +- soap_server: parse all "headers" from HTTP_SERVER_VARS (not just HTTP_*) +- soap_server: use PHP_SELF instead of SCRIPT_NAME for WSDL endpoint +- soap_server: when generating a fault while debug_flag is true, put debug into faultdetail +- wsdl: add enumeration parameter to addSimpleType +- xmlschema: add enumeration parameter to addSimpleType diff --git a/htdocs/includes/nusoap/lib/class.nusoap_base.php b/htdocs/includes/nusoap/lib/class.nusoap_base.php index fdf7fb7771daaeace3031f3972cd2cd5aada8d77..a74e83e0e03104217d48be0b145139291461be9a 100644 --- a/htdocs/includes/nusoap/lib/class.nusoap_base.php +++ b/htdocs/includes/nusoap/lib/class.nusoap_base.php @@ -1,905 +1,905 @@ -<?php - -/* -$Id$ - -NuSOAP - Web Services Toolkit for PHP - -Copyright (c) 2002 NuSphere Corporation - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -If you have any questions or comments, please email: - -Dietrich Ayala -dietrich@ganx4.com -http://dietrich.ganx4.com/nusoap - -NuSphere Corporation -http://www.nusphere.com - -*/ - -/* load classes - -// necessary classes -require_once('class.soapclient.php'); -require_once('class.soap_val.php'); -require_once('class.soap_parser.php'); -require_once('class.soap_fault.php'); - -// transport classes -require_once('class.soap_transport_http.php'); - -// optional add-on classes -require_once('class.xmlschema.php'); -require_once('class.wsdl.php'); - -// server class -require_once('class.soap_server.php');*/ - -// class variable emulation -// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html -$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; - -/** -* -* nusoap_base -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class nusoap_base { - /** - * Identification for HTTP headers. - * - * @var string - * @access private - */ - var $title = 'NuSOAP'; - /** - * Version for HTTP headers. - * - * @var string - * @access private - */ - var $version = '0.7.2'; - /** - * CVS revision for HTTP headers. - * - * @var string - * @access private - */ - var $revision = '$Revision$'; - /** - * Current error string (manipulated by getError/setError) - * - * @var string - * @access private - */ - var $error_str = ''; - /** - * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) - * - * @var string - * @access private - */ - var $debug_str = ''; - /** - * toggles automatic encoding of special characters as entities - * (should always be true, I think) - * - * @var boolean - * @access private - */ - var $charencoding = true; - /** - * the debug level for this instance - * - * @var integer - * @access private - */ - var $debugLevel; - - /** - * set schema version - * - * @var string - * @access public - */ - var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; - - /** - * charset encoding for outgoing messages - * - * @var string - * @access public - */ - var $soap_defencoding = 'ISO-8859-1'; - //var $soap_defencoding = 'UTF-8'; - - /** - * namespaces in an array of prefix => uri - * - * this is "seeded" by a set of constants, but it may be altered by code - * - * @var array - * @access public - */ - var $namespaces = array( - 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', - 'xsd' => 'http://www.w3.org/2001/XMLSchema', - 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' - ); - - /** - * namespaces used in the current context, e.g. during serialization - * - * @var array - * @access private - */ - var $usedNamespaces = array(); - - /** - * XML Schema types in an array of uri => (array of xml type => php type) - * is this legacy yet? - * no, this is used by the xmlschema class to verify type => namespace mappings. - * @var array - * @access public - */ - var $typemap = array( - 'http://www.w3.org/2001/XMLSchema' => array( - 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', - 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', - 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', - // abstract "any" types - 'anyType'=>'string','anySimpleType'=>'string', - // derived datatypes - 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', - 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', - 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', - 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), - 'http://www.w3.org/2000/10/XMLSchema' => array( - 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', - 'float'=>'double','dateTime'=>'string', - 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), - 'http://www.w3.org/1999/XMLSchema' => array( - 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', - 'float'=>'double','dateTime'=>'string', - 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), - 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), - 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), - 'http://xml.apache.org/xml-soap' => array('Map') - ); - - /** - * XML entities to convert - * - * @var array - * @access public - * @deprecated - * @see expandEntities - */ - var $xmlEntities = array('quot' => '"','amp' => '&', - 'lt' => '<','gt' => '>','apos' => "'"); - - /** - * constructor - * - * @access public - */ - function nusoap_base() { - $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; - } - - /** - * gets the global debug level, which applies to future instances - * - * @return integer Debug level 0-9, where 0 turns off - * @access public - */ - function getGlobalDebugLevel() { - return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; - } - - /** - * sets the global debug level, which applies to future instances - * - * @param int $level Debug level 0-9, where 0 turns off - * @access public - */ - function setGlobalDebugLevel($level) { - $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; - } - - /** - * gets the debug level for this instance - * - * @return int Debug level 0-9, where 0 turns off - * @access public - */ - function getDebugLevel() { - return $this->debugLevel; - } - - /** - * sets the debug level for this instance - * - * @param int $level Debug level 0-9, where 0 turns off - * @access public - */ - function setDebugLevel($level) { - $this->debugLevel = $level; - } - - /** - * adds debug data to the instance debug string with formatting - * - * @param string $string debug data - * @access private - */ - function debug($string){ - if ($this->debugLevel > 0) { - $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); - } - } - - /** - * adds debug data to the instance debug string without formatting - * - * @param string $string debug data - * @access public - */ - function appendDebug($string){ - if ($this->debugLevel > 0) { - // it would be nice to use a memory stream here to use - // memory more efficiently - $this->debug_str .= $string; - } - } - - /** - * clears the current debug data for this instance - * - * @access public - */ - function clearDebug() { - // it would be nice to use a memory stream here to use - // memory more efficiently - $this->debug_str = ''; - } - - /** - * gets the current debug data for this instance - * - * @return debug data - * @access public - */ - function &getDebug() { - // it would be nice to use a memory stream here to use - // memory more efficiently - return $this->debug_str; - } - - /** - * gets the current debug data for this instance as an XML comment - * this may change the contents of the debug data - * - * @return debug data as an XML comment - * @access public - */ - function &getDebugAsXMLComment() { - // it would be nice to use a memory stream here to use - // memory more efficiently - while (strpos($this->debug_str, '--')) { - $this->debug_str = str_replace('--', '- -', $this->debug_str); - } - return "<!--\n" . $this->debug_str . "\n-->"; - } - - /** - * expands entities, e.g. changes '<' to '<'. - * - * @param string $val The string in which to expand entities. - * @access private - */ - function expandEntities($val) { - if ($this->charencoding) { - $val = str_replace('&', '&', $val); - $val = str_replace("'", ''', $val); - $val = str_replace('"', '"', $val); - $val = str_replace('<', '<', $val); - $val = str_replace('>', '>', $val); - } - return $val; - } - - /** - * returns error string if present - * - * @return mixed error string or false - * @access public - */ - function getError(){ - if($this->error_str != ''){ - return $this->error_str; - } - return false; - } - - /** - * sets error string - * - * @return boolean $string error string - * @access private - */ - function setError($str){ - $this->error_str = $str; - } - - /** - * detect if array is a simple array or a struct (associative array) - * - * @param mixed $val The PHP array - * @return string (arraySimple|arrayStruct) - * @access private - */ - function isArraySimpleOrStruct($val) { - $keyList = array_keys($val); - foreach ($keyList as $keyListValue) { - if (!is_int($keyListValue)) { - return 'arrayStruct'; - } - } - return 'arraySimple'; - } - - /** - * serializes PHP values in accordance w/ section 5. Type information is - * not serialized if $use == 'literal'. - * - * @param mixed $val The value to serialize - * @param string $name The name (local part) of the XML element - * @param string $type The XML schema type (local part) for the element - * @param string $name_ns The namespace for the name of the XML element - * @param string $type_ns The namespace for the type of the element - * @param array $attributes The attributes to serialize as name=>value pairs - * @param string $use The WSDL "use" (encoded|literal) - * @return string The serialized element, possibly with child elements - * @access public - */ - function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ - $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); - $this->appendDebug('value=' . $this->varDump($val)); - $this->appendDebug('attributes=' . $this->varDump($attributes)); - - if(is_object($val) && get_class($val) == 'soapval'){ - return $val->serialize($use); - } - // force valid name if necessary - if (is_numeric($name)) { - $name = '__numeric_' . $name; - } elseif (! $name) { - $name = 'noname'; - } - // if name has ns, add ns prefix to name - $xmlns = ''; - if($name_ns){ - $prefix = 'nu'.rand(1000,9999); - $name = $prefix.':'.$name; - $xmlns .= " xmlns:$prefix=\"$name_ns\""; - } - // if type is prefixed, create type prefix - if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ - // need to fix this. shouldn't default to xsd if no ns specified - // w/o checking against typemap - $type_prefix = 'xsd'; - } elseif($type_ns){ - $type_prefix = 'ns'.rand(1000,9999); - $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; - } - // serialize attributes if present - $atts = ''; - if($attributes){ - foreach($attributes as $k => $v){ - $atts .= " $k=\"".$this->expandEntities($v).'"'; - } - } - // serialize null value - if (is_null($val)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - return "<$name$xmlns $atts/>"; - } else { - if (isset($type) && isset($type_prefix)) { - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = ''; - } - return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; - } - } - // serialize if an xsd built-in primitive type - if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ - if (is_bool($val)) { - if ($type == 'boolean') { - $val = $val ? 'true' : 'false'; - } elseif (! $val) { - $val = 0; - } - } else if (is_string($val)) { - $val = $this->expandEntities($val); - } - if ($use == 'literal') { - return "<$name$xmlns $atts>$val</$name>"; - } else { - return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>"; - } - } - // detect type and serialize - $xml = ''; - switch(true) { - case (is_bool($val) || $type == 'boolean'): - if ($type == 'boolean') { - $val = $val ? 'true' : 'false'; - } elseif (! $val) { - $val = 0; - } - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>"; - } - break; - case (is_int($val) || is_long($val) || $type == 'int'): - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>"; - } - break; - case (is_float($val)|| is_double($val) || $type == 'float'): - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>"; - } - break; - case (is_string($val) || $type == 'string'): - $val = $this->expandEntities($val); - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>"; - } - break; - case is_object($val): - if (! $name) { - $name = get_class($val); - $this->debug("In serialize_val, used class name $name as element name"); - } else { - $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); - } - foreach(get_object_vars($val) as $k => $v){ - $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); - } - $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>'; - break; - break; - case (is_array($val) || $type): - // detect if struct or array - $valueType = $this->isArraySimpleOrStruct($val); - if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ - $i = 0; - if(is_array($val) && count($val)> 0){ - foreach($val as $v){ - if(is_object($v) && get_class($v) == 'soapval'){ - $tt_ns = $v->type_ns; - $tt = $v->type; - } elseif (is_array($v)) { - $tt = $this->isArraySimpleOrStruct($v); - } else { - $tt = gettype($v); - } - $array_types[$tt] = 1; - // TODO: for literal, the name should be $name - $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); - ++$i; - } - if(count($array_types) > 1){ - $array_typename = 'xsd:anyType'; - } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { - if ($tt == 'integer') { - $tt = 'int'; - } - $array_typename = 'xsd:'.$tt; - } elseif(isset($tt) && $tt == 'arraySimple'){ - $array_typename = 'SOAP-ENC:Array'; - } elseif(isset($tt) && $tt == 'arrayStruct'){ - $array_typename = 'unnamed_struct_use_soapval'; - } else { - // if type is prefixed, create type prefix - if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ - $array_typename = 'xsd:' . $tt; - } elseif ($tt_ns) { - $tt_prefix = 'ns' . rand(1000, 9999); - $array_typename = "$tt_prefix:$tt"; - $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; - } else { - $array_typename = $tt; - } - } - $array_type = $i; - if ($use == 'literal') { - $type_str = ''; - } else if (isset($type) && isset($type_prefix)) { - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; - } - // empty array - } else { - if ($use == 'literal') { - $type_str = ''; - } else if (isset($type) && isset($type_prefix)) { - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; - } - } - // TODO: for array in literal, there is no wrapper here - $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>"; - } else { - // got a struct - if(isset($type) && isset($type_prefix)){ - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = ''; - } - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>"; - } else { - $xml .= "<$name$xmlns$type_str$atts>"; - } - foreach($val as $k => $v){ - // Apache Map - if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { - $xml .= '<item>'; - $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); - $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); - $xml .= '</item>'; - } else { - $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); - } - } - $xml .= "</$name>"; - } - break; - default: - $xml .= 'not detected, got '.gettype($val).' for '.$val; - break; - } - return $xml; - } - - /** - * serializes a message - * - * @param string $body the XML of the SOAP body - * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers - * @param array $namespaces optional the namespaces used in generating the body and headers - * @param string $style optional (rpc|document) - * @param string $use optional (encoded|literal) - * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) - * @return string the message - * @access public - */ - function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ - // TODO: add an option to automatically run utf8_encode on $body and $headers - // if $this->soap_defencoding is UTF-8. Not doing this automatically allows - // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 - - $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); - $this->debug("headers:"); - $this->appendDebug($this->varDump($headers)); - $this->debug("namespaces:"); - $this->appendDebug($this->varDump($namespaces)); - - // serialize namespaces - $ns_string = ''; - foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ - $ns_string .= " xmlns:$k=\"$v\""; - } - if($encodingStyle) { - $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; - } - - // serialize headers - if($headers){ - if (is_array($headers)) { - $xml = ''; - foreach ($headers as $header) { - $xml .= $this->serialize_val($header, false, false, false, false, false, $use); - } - $headers = $xml; - $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); - } - $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>"; - } - // serialize envelope - return - '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">". - '<SOAP-ENV:Envelope'.$ns_string.">". - $headers. - "<SOAP-ENV:Body>". - $body. - "</SOAP-ENV:Body>". - "</SOAP-ENV:Envelope>"; - } - - /** - * formats a string to be inserted into an HTML stream - * - * @param string $str The string to format - * @return string The formatted string - * @access public - * @deprecated - */ - function formatDump($str){ - $str = htmlspecialchars($str); - return nl2br($str); - } - - /** - * contracts (changes namespace to prefix) a qualified name - * - * @param string $qname qname - * @return string contracted qname - * @access private - */ - function contractQname($qname){ - // get element namespace - //$this->xdebug("Contract $qname"); - if (strrpos($qname, ':')) { - // get unqualified name - $name = substr($qname, strrpos($qname, ':') + 1); - // get ns - $ns = substr($qname, 0, strrpos($qname, ':')); - $p = $this->getPrefixFromNamespace($ns); - if ($p) { - return $p . ':' . $name; - } - return $qname; - } else { - return $qname; - } - } - - /** - * expands (changes prefix to namespace) a qualified name - * - * @param string $string qname - * @return string expanded qname - * @access private - */ - function expandQname($qname){ - // get element prefix - if(strpos($qname,':') && !ereg('^http://',$qname)){ - // get unqualified name - $name = substr(strstr($qname,':'),1); - // get ns prefix - $prefix = substr($qname,0,strpos($qname,':')); - if(isset($this->namespaces[$prefix])){ - return $this->namespaces[$prefix].':'.$name; - } else { - return $qname; - } - } else { - return $qname; - } - } - - /** - * returns the local part of a prefixed string - * returns the original string, if not prefixed - * - * @param string $str The prefixed string - * @return string The local part - * @access public - */ - function getLocalPart($str){ - if($sstr = strrchr($str,':')){ - // get unqualified name - return substr( $sstr, 1 ); - } else { - return $str; - } - } - - /** - * returns the prefix part of a prefixed string - * returns false, if not prefixed - * - * @param string $str The prefixed string - * @return mixed The prefix or false if there is no prefix - * @access public - */ - function getPrefix($str){ - if($pos = strrpos($str,':')){ - // get prefix - return substr($str,0,$pos); - } - return false; - } - - /** - * pass it a prefix, it returns a namespace - * - * @param string $prefix The prefix - * @return mixed The namespace, false if no namespace has the specified prefix - * @access public - */ - function getNamespaceFromPrefix($prefix){ - if (isset($this->namespaces[$prefix])) { - return $this->namespaces[$prefix]; - } - //$this->setError("No namespace registered for prefix '$prefix'"); - return false; - } - - /** - * returns the prefix for a given namespace (or prefix) - * or false if no prefixes registered for the given namespace - * - * @param string $ns The namespace - * @return mixed The prefix, false if the namespace has no prefixes - * @access public - */ - function getPrefixFromNamespace($ns) { - foreach ($this->namespaces as $p => $n) { - if ($ns == $n || $ns == $p) { - $this->usedNamespaces[$p] = $n; - return $p; - } - } - return false; - } - - /** - * returns the time in ODBC canonical form with microseconds - * - * @return string The time in ODBC canonical form with microseconds - * @access public - */ - function getmicrotime() { - if (function_exists('gettimeofday')) { - $tod = gettimeofday(); - $sec = $tod['sec']; - $usec = $tod['usec']; - } else { - $sec = time(); - $usec = 0; - } - return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); - } - - /** - * Returns a string with the output of var_dump - * - * @param mixed $data The variable to var_dump - * @return string The output of var_dump - * @access public - */ - function varDump($data) { - ob_start(); - var_dump($data); - $ret_val = ob_get_contents(); - ob_end_clean(); - return $ret_val; - } -} - -// XML Schema Datatype Helper Functions - -//xsd:dateTime helpers - -/** -* convert unix timestamp to ISO 8601 compliant date string -* -* @param string $timestamp Unix time stamp -* @access public -*/ -function timestamp_to_iso8601($timestamp,$utc=true){ - $datestr = date('Y-m-d\TH:i:sO',$timestamp); - if($utc){ - $eregStr = - '([0-9]{4})-'. // centuries & years CCYY- - '([0-9]{2})-'. // months MM- - '([0-9]{2})'. // days DD - 'T'. // separator T - '([0-9]{2}):'. // hours hh: - '([0-9]{2}):'. // minutes mm: - '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... - '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's - - if(ereg($eregStr,$datestr,$regs)){ - return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); - } - return false; - } else { - return $datestr; - } -} - -/** -* convert ISO 8601 compliant date string to unix timestamp -* -* @param string $datestr ISO 8601 compliant date string -* @access public -*/ -function iso8601_to_timestamp($datestr){ - $eregStr = - '([0-9]{4})-'. // centuries & years CCYY- - '([0-9]{2})-'. // months MM- - '([0-9]{2})'. // days DD - 'T'. // separator T - '([0-9]{2}):'. // hours hh: - '([0-9]{2}):'. // minutes mm: - '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... - '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's - if(ereg($eregStr,$datestr,$regs)){ - // not utc - if($regs[8] != 'Z'){ - $op = substr($regs[8],0,1); - $h = substr($regs[8],1,2); - $m = substr($regs[8],strlen($regs[8])-2,2); - if($op == '-'){ - $regs[4] = $regs[4] + $h; - $regs[5] = $regs[5] + $m; - } elseif($op == '+'){ - $regs[4] = $regs[4] - $h; - $regs[5] = $regs[5] - $m; - } - } - return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); - } else { - return false; - } -} - -/** -* sleeps some number of microseconds -* -* @param string $usec the number of microseconds to sleep -* @access public -* @deprecated -*/ -function usleepWindows($usec) -{ - $start = gettimeofday(); - - do - { - $stop = gettimeofday(); - $timePassed = 1000000 * ($stop['sec'] - $start['sec']) - + $stop['usec'] - $start['usec']; - } - while ($timePassed < $usec); -} - - +<?php + +/* +$Id$ + +NuSOAP - Web Services Toolkit for PHP + +Copyright (c) 2002 NuSphere Corporation + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you have any questions or comments, please email: + +Dietrich Ayala +dietrich@ganx4.com +http://dietrich.ganx4.com/nusoap + +NuSphere Corporation +http://www.nusphere.com + +*/ + +/* load classes + +// necessary classes +require_once('class.soapclient.php'); +require_once('class.soap_val.php'); +require_once('class.soap_parser.php'); +require_once('class.soap_fault.php'); + +// transport classes +require_once('class.soap_transport_http.php'); + +// optional add-on classes +require_once('class.xmlschema.php'); +require_once('class.wsdl.php'); + +// server class +require_once('class.soap_server.php');*/ + +// class variable emulation +// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html +$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; + +/** +* +* nusoap_base +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class nusoap_base { + /** + * Identification for HTTP headers. + * + * @var string + * @access private + */ + var $title = 'NuSOAP'; + /** + * Version for HTTP headers. + * + * @var string + * @access private + */ + var $version = '0.7.2'; + /** + * CVS revision for HTTP headers. + * + * @var string + * @access private + */ + var $revision = '$Revision$'; + /** + * Current error string (manipulated by getError/setError) + * + * @var string + * @access private + */ + var $error_str = ''; + /** + * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) + * + * @var string + * @access private + */ + var $debug_str = ''; + /** + * toggles automatic encoding of special characters as entities + * (should always be true, I think) + * + * @var boolean + * @access private + */ + var $charencoding = true; + /** + * the debug level for this instance + * + * @var integer + * @access private + */ + var $debugLevel; + + /** + * set schema version + * + * @var string + * @access public + */ + var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + /** + * charset encoding for outgoing messages + * + * @var string + * @access public + */ + var $soap_defencoding = 'ISO-8859-1'; + //var $soap_defencoding = 'UTF-8'; + + /** + * namespaces in an array of prefix => uri + * + * this is "seeded" by a set of constants, but it may be altered by code + * + * @var array + * @access public + */ + var $namespaces = array( + 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'xsd' => 'http://www.w3.org/2001/XMLSchema', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' + ); + + /** + * namespaces used in the current context, e.g. during serialization + * + * @var array + * @access private + */ + var $usedNamespaces = array(); + + /** + * XML Schema types in an array of uri => (array of xml type => php type) + * is this legacy yet? + * no, this is used by the xmlschema class to verify type => namespace mappings. + * @var array + * @access public + */ + var $typemap = array( + 'http://www.w3.org/2001/XMLSchema' => array( + 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', + 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', + 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', + // abstract "any" types + 'anyType'=>'string','anySimpleType'=>'string', + // derived datatypes + 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', + 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', + 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', + 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), + 'http://www.w3.org/2000/10/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://www.w3.org/1999/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), + 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), + 'http://xml.apache.org/xml-soap' => array('Map') + ); + + /** + * XML entities to convert + * + * @var array + * @access public + * @deprecated + * @see expandEntities + */ + var $xmlEntities = array('quot' => '"','amp' => '&', + 'lt' => '<','gt' => '>','apos' => "'"); + + /** + * constructor + * + * @access public + */ + function nusoap_base() { + $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * gets the global debug level, which applies to future instances + * + * @return integer Debug level 0-9, where 0 turns off + * @access public + */ + function getGlobalDebugLevel() { + return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * sets the global debug level, which applies to future instances + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setGlobalDebugLevel($level) { + $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; + } + + /** + * gets the debug level for this instance + * + * @return int Debug level 0-9, where 0 turns off + * @access public + */ + function getDebugLevel() { + return $this->debugLevel; + } + + /** + * sets the debug level for this instance + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setDebugLevel($level) { + $this->debugLevel = $level; + } + + /** + * adds debug data to the instance debug string with formatting + * + * @param string $string debug data + * @access private + */ + function debug($string){ + if ($this->debugLevel > 0) { + $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); + } + } + + /** + * adds debug data to the instance debug string without formatting + * + * @param string $string debug data + * @access public + */ + function appendDebug($string){ + if ($this->debugLevel > 0) { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str .= $string; + } + } + + /** + * clears the current debug data for this instance + * + * @access public + */ + function clearDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str = ''; + } + + /** + * gets the current debug data for this instance + * + * @return debug data + * @access public + */ + function &getDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + return $this->debug_str; + } + + /** + * gets the current debug data for this instance as an XML comment + * this may change the contents of the debug data + * + * @return debug data as an XML comment + * @access public + */ + function &getDebugAsXMLComment() { + // it would be nice to use a memory stream here to use + // memory more efficiently + while (strpos($this->debug_str, '--')) { + $this->debug_str = str_replace('--', '- -', $this->debug_str); + } + return "<!--\n" . $this->debug_str . "\n-->"; + } + + /** + * expands entities, e.g. changes '<' to '<'. + * + * @param string $val The string in which to expand entities. + * @access private + */ + function expandEntities($val) { + if ($this->charencoding) { + $val = str_replace('&', '&', $val); + $val = str_replace("'", ''', $val); + $val = str_replace('"', '"', $val); + $val = str_replace('<', '<', $val); + $val = str_replace('>', '>', $val); + } + return $val; + } + + /** + * returns error string if present + * + * @return mixed error string or false + * @access public + */ + function getError(){ + if($this->error_str != ''){ + return $this->error_str; + } + return false; + } + + /** + * sets error string + * + * @return boolean $string error string + * @access private + */ + function setError($str){ + $this->error_str = $str; + } + + /** + * detect if array is a simple array or a struct (associative array) + * + * @param mixed $val The PHP array + * @return string (arraySimple|arrayStruct) + * @access private + */ + function isArraySimpleOrStruct($val) { + $keyList = array_keys($val); + foreach ($keyList as $keyListValue) { + if (!is_int($keyListValue)) { + return 'arrayStruct'; + } + } + return 'arraySimple'; + } + + /** + * serializes PHP values in accordance w/ section 5. Type information is + * not serialized if $use == 'literal'. + * + * @param mixed $val The value to serialize + * @param string $name The name (local part) of the XML element + * @param string $type The XML schema type (local part) for the element + * @param string $name_ns The namespace for the name of the XML element + * @param string $type_ns The namespace for the type of the element + * @param array $attributes The attributes to serialize as name=>value pairs + * @param string $use The WSDL "use" (encoded|literal) + * @return string The serialized element, possibly with child elements + * @access public + */ + function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ + $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); + $this->appendDebug('value=' . $this->varDump($val)); + $this->appendDebug('attributes=' . $this->varDump($attributes)); + + if(is_object($val) && get_class($val) == 'soapval'){ + return $val->serialize($use); + } + // force valid name if necessary + if (is_numeric($name)) { + $name = '__numeric_' . $name; + } elseif (! $name) { + $name = 'noname'; + } + // if name has ns, add ns prefix to name + $xmlns = ''; + if($name_ns){ + $prefix = 'nu'.rand(1000,9999); + $name = $prefix.':'.$name; + $xmlns .= " xmlns:$prefix=\"$name_ns\""; + } + // if type is prefixed, create type prefix + if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ + // need to fix this. shouldn't default to xsd if no ns specified + // w/o checking against typemap + $type_prefix = 'xsd'; + } elseif($type_ns){ + $type_prefix = 'ns'.rand(1000,9999); + $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; + } + // serialize attributes if present + $atts = ''; + if($attributes){ + foreach($attributes as $k => $v){ + $atts .= " $k=\"".$this->expandEntities($v).'"'; + } + } + // serialize null value + if (is_null($val)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + return "<$name$xmlns $atts/>"; + } else { + if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; + } + } + // serialize if an xsd built-in primitive type + if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ + if (is_bool($val)) { + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + } else if (is_string($val)) { + $val = $this->expandEntities($val); + } + if ($use == 'literal') { + return "<$name$xmlns $atts>$val</$name>"; + } else { + return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>"; + } + } + // detect type and serialize + $xml = ''; + switch(true) { + case (is_bool($val) || $type == 'boolean'): + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>"; + } + break; + case (is_int($val) || is_long($val) || $type == 'int'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>"; + } + break; + case (is_float($val)|| is_double($val) || $type == 'float'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>"; + } + break; + case (is_string($val) || $type == 'string'): + $val = $this->expandEntities($val); + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>"; + } + break; + case is_object($val): + if (! $name) { + $name = get_class($val); + $this->debug("In serialize_val, used class name $name as element name"); + } else { + $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); + } + foreach(get_object_vars($val) as $k => $v){ + $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); + } + $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>'; + break; + break; + case (is_array($val) || $type): + // detect if struct or array + $valueType = $this->isArraySimpleOrStruct($val); + if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ + $i = 0; + if(is_array($val) && count($val)> 0){ + foreach($val as $v){ + if(is_object($v) && get_class($v) == 'soapval'){ + $tt_ns = $v->type_ns; + $tt = $v->type; + } elseif (is_array($v)) { + $tt = $this->isArraySimpleOrStruct($v); + } else { + $tt = gettype($v); + } + $array_types[$tt] = 1; + // TODO: for literal, the name should be $name + $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); + ++$i; + } + if(count($array_types) > 1){ + $array_typename = 'xsd:anyType'; + } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { + if ($tt == 'integer') { + $tt = 'int'; + } + $array_typename = 'xsd:'.$tt; + } elseif(isset($tt) && $tt == 'arraySimple'){ + $array_typename = 'SOAP-ENC:Array'; + } elseif(isset($tt) && $tt == 'arrayStruct'){ + $array_typename = 'unnamed_struct_use_soapval'; + } else { + // if type is prefixed, create type prefix + if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ + $array_typename = 'xsd:' . $tt; + } elseif ($tt_ns) { + $tt_prefix = 'ns' . rand(1000, 9999); + $array_typename = "$tt_prefix:$tt"; + $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; + } else { + $array_typename = $tt; + } + } + $array_type = $i; + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; + } + // empty array + } else { + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; + } + } + // TODO: for array in literal, there is no wrapper here + $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>"; + } else { + // got a struct + if(isset($type) && isset($type_prefix)){ + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>"; + } else { + $xml .= "<$name$xmlns$type_str$atts>"; + } + foreach($val as $k => $v){ + // Apache Map + if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { + $xml .= '<item>'; + $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); + $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); + $xml .= '</item>'; + } else { + $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } + $xml .= "</$name>"; + } + break; + default: + $xml .= 'not detected, got '.gettype($val).' for '.$val; + break; + } + return $xml; + } + + /** + * serializes a message + * + * @param string $body the XML of the SOAP body + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param array $namespaces optional the namespaces used in generating the body and headers + * @param string $style optional (rpc|document) + * @param string $use optional (encoded|literal) + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @return string the message + * @access public + */ + function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ + // TODO: add an option to automatically run utf8_encode on $body and $headers + // if $this->soap_defencoding is UTF-8. Not doing this automatically allows + // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 + + $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); + $this->debug("headers:"); + $this->appendDebug($this->varDump($headers)); + $this->debug("namespaces:"); + $this->appendDebug($this->varDump($namespaces)); + + // serialize namespaces + $ns_string = ''; + foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ + $ns_string .= " xmlns:$k=\"$v\""; + } + if($encodingStyle) { + $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; + } + + // serialize headers + if($headers){ + if (is_array($headers)) { + $xml = ''; + foreach ($headers as $header) { + $xml .= $this->serialize_val($header, false, false, false, false, false, $use); + } + $headers = $xml; + $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); + } + $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>"; + } + // serialize envelope + return + '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">". + '<SOAP-ENV:Envelope'.$ns_string.">". + $headers. + "<SOAP-ENV:Body>". + $body. + "</SOAP-ENV:Body>". + "</SOAP-ENV:Envelope>"; + } + + /** + * formats a string to be inserted into an HTML stream + * + * @param string $str The string to format + * @return string The formatted string + * @access public + * @deprecated + */ + function formatDump($str){ + $str = htmlspecialchars($str); + return nl2br($str); + } + + /** + * contracts (changes namespace to prefix) a qualified name + * + * @param string $qname qname + * @return string contracted qname + * @access private + */ + function contractQname($qname){ + // get element namespace + //$this->xdebug("Contract $qname"); + if (strrpos($qname, ':')) { + // get unqualified name + $name = substr($qname, strrpos($qname, ':') + 1); + // get ns + $ns = substr($qname, 0, strrpos($qname, ':')); + $p = $this->getPrefixFromNamespace($ns); + if ($p) { + return $p . ':' . $name; + } + return $qname; + } else { + return $qname; + } + } + + /** + * expands (changes prefix to namespace) a qualified name + * + * @param string $string qname + * @return string expanded qname + * @access private + */ + function expandQname($qname){ + // get element prefix + if(strpos($qname,':') && !ereg('^http://',$qname)){ + // get unqualified name + $name = substr(strstr($qname,':'),1); + // get ns prefix + $prefix = substr($qname,0,strpos($qname,':')); + if(isset($this->namespaces[$prefix])){ + return $this->namespaces[$prefix].':'.$name; + } else { + return $qname; + } + } else { + return $qname; + } + } + + /** + * returns the local part of a prefixed string + * returns the original string, if not prefixed + * + * @param string $str The prefixed string + * @return string The local part + * @access public + */ + function getLocalPart($str){ + if($sstr = strrchr($str,':')){ + // get unqualified name + return substr( $sstr, 1 ); + } else { + return $str; + } + } + + /** + * returns the prefix part of a prefixed string + * returns false, if not prefixed + * + * @param string $str The prefixed string + * @return mixed The prefix or false if there is no prefix + * @access public + */ + function getPrefix($str){ + if($pos = strrpos($str,':')){ + // get prefix + return substr($str,0,$pos); + } + return false; + } + + /** + * pass it a prefix, it returns a namespace + * + * @param string $prefix The prefix + * @return mixed The namespace, false if no namespace has the specified prefix + * @access public + */ + function getNamespaceFromPrefix($prefix){ + if (isset($this->namespaces[$prefix])) { + return $this->namespaces[$prefix]; + } + //$this->setError("No namespace registered for prefix '$prefix'"); + return false; + } + + /** + * returns the prefix for a given namespace (or prefix) + * or false if no prefixes registered for the given namespace + * + * @param string $ns The namespace + * @return mixed The prefix, false if the namespace has no prefixes + * @access public + */ + function getPrefixFromNamespace($ns) { + foreach ($this->namespaces as $p => $n) { + if ($ns == $n || $ns == $p) { + $this->usedNamespaces[$p] = $n; + return $p; + } + } + return false; + } + + /** + * returns the time in ODBC canonical form with microseconds + * + * @return string The time in ODBC canonical form with microseconds + * @access public + */ + function getmicrotime() { + if (function_exists('gettimeofday')) { + $tod = gettimeofday(); + $sec = $tod['sec']; + $usec = $tod['usec']; + } else { + $sec = time(); + $usec = 0; + } + return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); + } + + /** + * Returns a string with the output of var_dump + * + * @param mixed $data The variable to var_dump + * @return string The output of var_dump + * @access public + */ + function varDump($data) { + ob_start(); + var_dump($data); + $ret_val = ob_get_contents(); + ob_end_clean(); + return $ret_val; + } +} + +// XML Schema Datatype Helper Functions + +//xsd:dateTime helpers + +/** +* convert unix timestamp to ISO 8601 compliant date string +* +* @param string $timestamp Unix time stamp +* @access public +*/ +function timestamp_to_iso8601($timestamp,$utc=true){ + $datestr = date('Y-m-d\TH:i:sO',$timestamp); + if($utc){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + + if(ereg($eregStr,$datestr,$regs)){ + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); + } + return false; + } else { + return $datestr; + } +} + +/** +* convert ISO 8601 compliant date string to unix timestamp +* +* @param string $datestr ISO 8601 compliant date string +* @access public +*/ +function iso8601_to_timestamp($datestr){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + if(ereg($eregStr,$datestr,$regs)){ + // not utc + if($regs[8] != 'Z'){ + $op = substr($regs[8],0,1); + $h = substr($regs[8],1,2); + $m = substr($regs[8],strlen($regs[8])-2,2); + if($op == '-'){ + $regs[4] = $regs[4] + $h; + $regs[5] = $regs[5] + $m; + } elseif($op == '+'){ + $regs[4] = $regs[4] - $h; + $regs[5] = $regs[5] - $m; + } + } + return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); + } else { + return false; + } +} + +/** +* sleeps some number of microseconds +* +* @param string $usec the number of microseconds to sleep +* @access public +* @deprecated +*/ +function usleepWindows($usec) +{ + $start = gettimeofday(); + + do + { + $stop = gettimeofday(); + $timePassed = 1000000 * ($stop['sec'] - $start['sec']) + + $stop['usec'] - $start['usec']; + } + while ($timePassed < $usec); +} + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.soap_fault.php b/htdocs/includes/nusoap/lib/class.soap_fault.php index d6859084e2bf03dc8eb35293727a71aa2026344f..62509a24fb22345c7d3cac67366440b460e9f099 100644 --- a/htdocs/includes/nusoap/lib/class.soap_fault.php +++ b/htdocs/includes/nusoap/lib/class.soap_fault.php @@ -1,86 +1,86 @@ -<?php - - - - -/** -* Contains information for a SOAP fault. -* Mainly used for returning faults from deployed functions -* in a server instance. -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_fault extends nusoap_base { - /** - * The fault code (client|server) - * @var string - * @access private - */ - var $faultcode; - /** - * The fault actor - * @var string - * @access private - */ - var $faultactor; - /** - * The fault string, a description of the fault - * @var string - * @access private - */ - var $faultstring; - /** - * The fault detail, typically a string or array of string - * @var mixed - * @access private - */ - var $faultdetail; - - /** - * constructor - * - * @param string $faultcode (client | server) - * @param string $faultactor only used when msg routed between multiple actors - * @param string $faultstring human readable error message - * @param mixed $faultdetail detail, typically a string or array of string - */ - function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ - parent::nusoap_base(); - $this->faultcode = $faultcode; - $this->faultactor = $faultactor; - $this->faultstring = $faultstring; - $this->faultdetail = $faultdetail; - } - - /** - * serialize a fault - * - * @return string The serialization of the fault instance. - * @access public - */ - function serialize(){ - $ns_string = ''; - foreach($this->namespaces as $k => $v){ - $ns_string .= "\n xmlns:$k=\"$v\""; - } - $return_msg = - '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'. - '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n". - '<SOAP-ENV:Body>'. - '<SOAP-ENV:Fault>'. - $this->serialize_val($this->faultcode, 'faultcode'). - $this->serialize_val($this->faultactor, 'faultactor'). - $this->serialize_val($this->faultstring, 'faultstring'). - $this->serialize_val($this->faultdetail, 'detail'). - '</SOAP-ENV:Fault>'. - '</SOAP-ENV:Body>'. - '</SOAP-ENV:Envelope>'; - return $return_msg; - } -} - - - - +<?php + + + + +/** +* Contains information for a SOAP fault. +* Mainly used for returning faults from deployed functions +* in a server instance. +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_fault extends nusoap_base { + /** + * The fault code (client|server) + * @var string + * @access private + */ + var $faultcode; + /** + * The fault actor + * @var string + * @access private + */ + var $faultactor; + /** + * The fault string, a description of the fault + * @var string + * @access private + */ + var $faultstring; + /** + * The fault detail, typically a string or array of string + * @var mixed + * @access private + */ + var $faultdetail; + + /** + * constructor + * + * @param string $faultcode (client | server) + * @param string $faultactor only used when msg routed between multiple actors + * @param string $faultstring human readable error message + * @param mixed $faultdetail detail, typically a string or array of string + */ + function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ + parent::nusoap_base(); + $this->faultcode = $faultcode; + $this->faultactor = $faultactor; + $this->faultstring = $faultstring; + $this->faultdetail = $faultdetail; + } + + /** + * serialize a fault + * + * @return string The serialization of the fault instance. + * @access public + */ + function serialize(){ + $ns_string = ''; + foreach($this->namespaces as $k => $v){ + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'. + '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n". + '<SOAP-ENV:Body>'. + '<SOAP-ENV:Fault>'. + $this->serialize_val($this->faultcode, 'faultcode'). + $this->serialize_val($this->faultactor, 'faultactor'). + $this->serialize_val($this->faultstring, 'faultstring'). + $this->serialize_val($this->faultdetail, 'detail'). + '</SOAP-ENV:Fault>'. + '</SOAP-ENV:Body>'. + '</SOAP-ENV:Envelope>'; + return $return_msg; + } +} + + + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.soap_parser.php b/htdocs/includes/nusoap/lib/class.soap_parser.php index 37b1920fc0e9a153a5ee9f5b201291e3c00d1daa..1c70a8cbdc123b714aed65348e385b438e44b8c0 100644 --- a/htdocs/includes/nusoap/lib/class.soap_parser.php +++ b/htdocs/includes/nusoap/lib/class.soap_parser.php @@ -1,599 +1,599 @@ -<?php - - - - -/** -* -* soap_parser class parses SOAP XML messages into native PHP values -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_parser extends nusoap_base { - - var $xml = ''; - var $xml_encoding = ''; - var $method = ''; - var $root_struct = ''; - var $root_struct_name = ''; - var $root_struct_namespace = ''; - var $root_header = ''; - var $document = ''; // incoming SOAP body (text) - // determines where in the message we are (envelope,header,body,method) - var $status = ''; - var $position = 0; - var $depth = 0; - var $default_namespace = ''; - var $namespaces = array(); - var $message = array(); - var $parent = ''; - var $fault = false; - var $fault_code = ''; - var $fault_str = ''; - var $fault_detail = ''; - var $depth_array = array(); - var $debug_flag = true; - var $soapresponse = NULL; - var $responseHeaders = ''; // incoming SOAP headers (text) - var $body_position = 0; - // for multiref parsing: - // array of id => pos - var $ids = array(); - // array of id => hrefs => pos - var $multirefs = array(); - // toggle for auto-decoding element content - var $decode_utf8 = true; - - /** - * constructor that actually does the parsing - * - * @param string $xml SOAP message - * @param string $encoding character encoding scheme of message - * @param string $method method for which XML is parsed (unused?) - * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 - * @access public - */ - function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ - parent::nusoap_base(); - $this->xml = $xml; - $this->xml_encoding = $encoding; - $this->method = $method; - $this->decode_utf8 = $decode_utf8; - - // Check whether content has been read. - if(!empty($xml)){ - // Check XML encoding - $pos_xml = strpos($xml, '<?xml'); - if ($pos_xml !== FALSE) { - $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1); - if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { - $xml_encoding = $res[1]; - if (strtoupper($xml_encoding) != $encoding) { - $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; - $this->debug($err); - if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { - $this->setError($err); - return; - } - // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed - } else { - $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); - } - } else { - $this->debug('No encoding specified in XML declaration'); - } - } else { - $this->debug('No XML declaration'); - } - $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); - // Create an XML parser - why not xml_parser_create_ns? - $this->parser = xml_parser_create($this->xml_encoding); - // Set the options for parsing the XML data. - //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); - xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); - xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); - // Set the object for the parser. - xml_set_object($this->parser, $this); - // Set the element handlers for the parser. - xml_set_element_handler($this->parser, 'start_element','end_element'); - xml_set_character_data_handler($this->parser,'character_data'); - - // Parse the XML file. - if(!xml_parse($this->parser,$xml,true)){ - // Display an error message. - $err = sprintf('XML error parsing SOAP payload on line %d: %s', - xml_get_current_line_number($this->parser), - xml_error_string(xml_get_error_code($this->parser))); - $this->debug($err); - $this->debug("XML payload:\n" . $xml); - $this->setError($err); - } else { - $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); - // get final value - $this->soapresponse = $this->message[$this->root_struct]['result']; - // get header value: no, because this is documented as XML string -// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ -// $this->responseHeaders = $this->message[$this->root_header]['result']; -// } - // resolve hrefs/ids - if(sizeof($this->multirefs) > 0){ - foreach($this->multirefs as $id => $hrefs){ - $this->debug('resolving multirefs for id: '.$id); - $idVal = $this->buildVal($this->ids[$id]); - if (is_array($idVal) && isset($idVal['!id'])) { - unset($idVal['!id']); - } - foreach($hrefs as $refPos => $ref){ - $this->debug('resolving href at pos '.$refPos); - $this->multirefs[$id][$refPos] = $idVal; - } - } - } - } - xml_parser_free($this->parser); - } else { - $this->debug('xml was empty, didn\'t parse!'); - $this->setError('xml was empty, didn\'t parse!'); - } - } - - /** - * start-element handler - * - * @param resource $parser XML parser object - * @param string $name element name - * @param array $attrs associative array of attributes - * @access private - */ - function start_element($parser, $name, $attrs) { - // position in a total number of elements, starting from 0 - // update class level pos - $pos = $this->position++; - // and set mine - $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); - // depth = how many levels removed from root? - // set mine as current global depth and increment global depth value - $this->message[$pos]['depth'] = $this->depth++; - - // else add self as child to whoever the current parent is - if($pos != 0){ - $this->message[$this->parent]['children'] .= '|'.$pos; - } - // set my parent - $this->message[$pos]['parent'] = $this->parent; - // set self as current parent - $this->parent = $pos; - // set self as current value for this depth - $this->depth_array[$this->depth] = $pos; - // get element prefix - if(strpos($name,':')){ - // get ns prefix - $prefix = substr($name,0,strpos($name,':')); - // get unqualified name - $name = substr(strstr($name,':'),1); - } - // set status - if($name == 'Envelope'){ - $this->status = 'envelope'; - } elseif($name == 'Header'){ - $this->root_header = $pos; - $this->status = 'header'; - } elseif($name == 'Body'){ - $this->status = 'body'; - $this->body_position = $pos; - // set method - } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ - $this->status = 'method'; - $this->root_struct_name = $name; - $this->root_struct = $pos; - $this->message[$pos]['type'] = 'struct'; - $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); - } - // set my status - $this->message[$pos]['status'] = $this->status; - // set name - $this->message[$pos]['name'] = htmlspecialchars($name); - // set attrs - $this->message[$pos]['attrs'] = $attrs; - - // loop through atts, logging ns and type declarations - $attstr = ''; - foreach($attrs as $key => $value){ - $key_prefix = $this->getPrefix($key); - $key_localpart = $this->getLocalPart($key); - // if ns declarations, add to class level array of valid namespaces - if($key_prefix == 'xmlns'){ - if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ - $this->XMLSchemaVersion = $value; - $this->namespaces['xsd'] = $this->XMLSchemaVersion; - $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; - } - $this->namespaces[$key_localpart] = $value; - // set method namespace - if($name == $this->root_struct_name){ - $this->methodNamespace = $value; - } - // if it's a type declaration, set type - } elseif($key_localpart == 'type'){ - $value_prefix = $this->getPrefix($value); - $value_localpart = $this->getLocalPart($value); - $this->message[$pos]['type'] = $value_localpart; - $this->message[$pos]['typePrefix'] = $value_prefix; - if(isset($this->namespaces[$value_prefix])){ - $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; - } else if(isset($attrs['xmlns:'.$value_prefix])) { - $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; - } - // should do something here with the namespace of specified type? - } elseif($key_localpart == 'arrayType'){ - $this->message[$pos]['type'] = 'array'; - /* do arrayType ereg here - [1] arrayTypeValue ::= atype asize - [2] atype ::= QName rank* - [3] rank ::= '[' (',')* ']' - [4] asize ::= '[' length~ ']' - [5] length ::= nextDimension* Digit+ - [6] nextDimension ::= Digit+ ',' - */ - $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; - if(ereg($expr,$value,$regs)){ - $this->message[$pos]['typePrefix'] = $regs[1]; - $this->message[$pos]['arrayTypePrefix'] = $regs[1]; - if (isset($this->namespaces[$regs[1]])) { - $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; - } else if (isset($attrs['xmlns:'.$regs[1]])) { - $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; - } - $this->message[$pos]['arrayType'] = $regs[2]; - $this->message[$pos]['arraySize'] = $regs[3]; - $this->message[$pos]['arrayCols'] = $regs[4]; - } - // specifies nil value (or not) - } elseif ($key_localpart == 'nil'){ - $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); - // some other attribute - } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { - $this->message[$pos]['xattrs']['!' . $key] = $value; - } - - if ($key == 'xmlns') { - $this->default_namespace = $value; - } - // log id - if($key == 'id'){ - $this->ids[$value] = $pos; - } - // root - if($key_localpart == 'root' && $value == 1){ - $this->status = 'method'; - $this->root_struct_name = $name; - $this->root_struct = $pos; - $this->debug("found root struct $this->root_struct_name, pos $pos"); - } - // for doclit - $attstr .= " $key=\"$value\""; - } - // get namespace - must be done after namespace atts are processed - if(isset($prefix)){ - $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; - $this->default_namespace = $this->namespaces[$prefix]; - } else { - $this->message[$pos]['namespace'] = $this->default_namespace; - } - if($this->status == 'header'){ - if ($this->root_header != $pos) { - $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; - } - } elseif($this->root_struct_name != ''){ - $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; - } - } - - /** - * end-element handler - * - * @param resource $parser XML parser object - * @param string $name element name - * @access private - */ - function end_element($parser, $name) { - // position of current element is equal to the last value left in depth_array for my depth - $pos = $this->depth_array[$this->depth--]; - - // get element prefix - if(strpos($name,':')){ - // get ns prefix - $prefix = substr($name,0,strpos($name,':')); - // get unqualified name - $name = substr(strstr($name,':'),1); - } - - // build to native type - if(isset($this->body_position) && $pos > $this->body_position){ - // deal w/ multirefs - if(isset($this->message[$pos]['attrs']['href'])){ - // get id - $id = substr($this->message[$pos]['attrs']['href'],1); - // add placeholder to href array - $this->multirefs[$id][$pos] = 'placeholder'; - // add set a reference to it as the result value - $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; - // build complexType values - } elseif($this->message[$pos]['children'] != ''){ - // if result has already been generated (struct/array) - if(!isset($this->message[$pos]['result'])){ - $this->message[$pos]['result'] = $this->buildVal($pos); - } - // build complexType values of attributes and possibly simpleContent - } elseif (isset($this->message[$pos]['xattrs'])) { - if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { - $this->message[$pos]['xattrs']['!'] = null; - } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { - if (isset($this->message[$pos]['type'])) { - $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } else { - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } else { - $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; - } - } - } - $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; - // set value of simpleType (or nil complexType) - } else { - //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); - if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { - $this->message[$pos]['xattrs']['!'] = null; - } elseif (isset($this->message[$pos]['type'])) { - $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } else { - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } else { - $this->message[$pos]['result'] = $this->message[$pos]['cdata']; - } - } - - /* add value to parent's result, if parent is struct/array - $parent = $this->message[$pos]['parent']; - if($this->message[$parent]['type'] != 'map'){ - if(strtolower($this->message[$parent]['type']) == 'array'){ - $this->message[$parent]['result'][] = $this->message[$pos]['result']; - } else { - $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; - } - } - */ - } - } - - // for doclit - if($this->status == 'header'){ - if ($this->root_header != $pos) { - $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; - } - } elseif($pos >= $this->root_struct){ - $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; - } - // switch status - if($pos == $this->root_struct){ - $this->status = 'body'; - $this->root_struct_namespace = $this->message[$pos]['namespace']; - } elseif($name == 'Body'){ - $this->status = 'envelope'; - } elseif($name == 'Header'){ - $this->status = 'envelope'; - } elseif($name == 'Envelope'){ - // - } - // set parent back to my parent - $this->parent = $this->message[$pos]['parent']; - } - - /** - * element content handler - * - * @param resource $parser XML parser object - * @param string $data element content - * @access private - */ - function character_data($parser, $data){ - $pos = $this->depth_array[$this->depth]; - if ($this->xml_encoding=='UTF-8'){ - // TODO: add an option to disable this for folks who want - // raw UTF-8 that, e.g., might not map to iso-8859-1 - // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); - if($this->decode_utf8){ - $data = utf8_decode($data); - } - } - $this->message[$pos]['cdata'] .= $data; - // for doclit - if($this->status == 'header'){ - $this->responseHeaders .= $data; - } else { - $this->document .= $data; - } - } - - /** - * get the parsed message - * - * @return mixed - * @access public - */ - function get_response(){ - return $this->soapresponse; - } - - /** - * get the parsed headers - * - * @return string XML or empty if no headers - * @access public - */ - function getHeaders(){ - return $this->responseHeaders; - } - - /** - * decodes simple types into PHP variables - * - * @param string $value value to decode - * @param string $type XML type to decode - * @param string $typens XML type namespace to decode - * @return mixed PHP value - * @access private - */ - function decodeSimple($value, $type, $typens) { - // TODO: use the namespace! - if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { - return (string) $value; - } - if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { - return (int) $value; - } - if ($type == 'float' || $type == 'double' || $type == 'decimal') { - return (double) $value; - } - if ($type == 'boolean') { - if (strtolower($value) == 'false' || strtolower($value) == 'f') { - return false; - } - return (boolean) $value; - } - if ($type == 'base64' || $type == 'base64Binary') { - $this->debug('Decode base64 value'); - return base64_decode($value); - } - // obscure numeric types - if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' - || $type == 'nonNegativeInteger' || $type == 'positiveInteger' - || $type == 'unsignedInt' - || $type == 'unsignedShort' || $type == 'unsignedByte') { - return (int) $value; - } - // bogus: parser treats array with no elements as a simple type - if ($type == 'array') { - return array(); - } - // everything else - return (string) $value; - } - - /** - * builds response structures for compound values (arrays/structs) - * and scalars - * - * @param integer $pos position in node tree - * @return mixed PHP value - * @access private - */ - function buildVal($pos){ - if(!isset($this->message[$pos]['type'])){ - $this->message[$pos]['type'] = ''; - } - $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); - // if there are children... - if($this->message[$pos]['children'] != ''){ - $this->debug('in buildVal, there are children'); - $children = explode('|',$this->message[$pos]['children']); - array_shift($children); // knock off empty - // md array - if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ - $r=0; // rowcount - $c=0; // colcount - foreach($children as $child_pos){ - $this->debug("in buildVal, got an MD array element: $r, $c"); - $params[$r][] = $this->message[$child_pos]['result']; - $c++; - if($c == $this->message[$pos]['arrayCols']){ - $c = 0; - $r++; - } - } - // array - } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ - $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); - foreach($children as $child_pos){ - $params[] = &$this->message[$child_pos]['result']; - } - // apache Map type: java hashtable - } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ - $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); - foreach($children as $child_pos){ - $kv = explode("|",$this->message[$child_pos]['children']); - $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; - } - // generic compound type - //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { - } else { - // Apache Vector type: treat as an array - $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); - if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { - $notstruct = 1; - } else { - $notstruct = 0; - } - // - foreach($children as $child_pos){ - if($notstruct){ - $params[] = &$this->message[$child_pos]['result']; - } else { - if (isset($params[$this->message[$child_pos]['name']])) { - // de-serialize repeated element name into an array - if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { - $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); - } - $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; - } else { - $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; - } - } - } - } - if (isset($this->message[$pos]['xattrs'])) { - $this->debug('in buildVal, handling attributes'); - foreach ($this->message[$pos]['xattrs'] as $n => $v) { - $params[$n] = $v; - } - } - // handle simpleContent - if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { - $this->debug('in buildVal, handling simpleContent'); - if (isset($this->message[$pos]['type'])) { - $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } else { - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } else { - $params['!'] = $this->message[$pos]['cdata']; - } - } - } - return is_array($params) ? $params : array(); - } else { - $this->debug('in buildVal, no children, building scalar'); - $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; - if (isset($this->message[$pos]['type'])) { - return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } - return $this->message[$pos]['cdata']; - } - } -} - - - - +<?php + + + + +/** +* +* soap_parser class parses SOAP XML messages into native PHP values +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_parser extends nusoap_base { + + var $xml = ''; + var $xml_encoding = ''; + var $method = ''; + var $root_struct = ''; + var $root_struct_name = ''; + var $root_struct_namespace = ''; + var $root_header = ''; + var $document = ''; // incoming SOAP body (text) + // determines where in the message we are (envelope,header,body,method) + var $status = ''; + var $position = 0; + var $depth = 0; + var $default_namespace = ''; + var $namespaces = array(); + var $message = array(); + var $parent = ''; + var $fault = false; + var $fault_code = ''; + var $fault_str = ''; + var $fault_detail = ''; + var $depth_array = array(); + var $debug_flag = true; + var $soapresponse = NULL; + var $responseHeaders = ''; // incoming SOAP headers (text) + var $body_position = 0; + // for multiref parsing: + // array of id => pos + var $ids = array(); + // array of id => hrefs => pos + var $multirefs = array(); + // toggle for auto-decoding element content + var $decode_utf8 = true; + + /** + * constructor that actually does the parsing + * + * @param string $xml SOAP message + * @param string $encoding character encoding scheme of message + * @param string $method method for which XML is parsed (unused?) + * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 + * @access public + */ + function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ + parent::nusoap_base(); + $this->xml = $xml; + $this->xml_encoding = $encoding; + $this->method = $method; + $this->decode_utf8 = $decode_utf8; + + // Check whether content has been read. + if(!empty($xml)){ + // Check XML encoding + $pos_xml = strpos($xml, '<?xml'); + if ($pos_xml !== FALSE) { + $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1); + if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { + $xml_encoding = $res[1]; + if (strtoupper($xml_encoding) != $encoding) { + $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; + $this->debug($err); + if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { + $this->setError($err); + return; + } + // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed + } else { + $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); + } + } else { + $this->debug('No encoding specified in XML declaration'); + } + } else { + $this->debug('No XML declaration'); + } + $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); + // Create an XML parser - why not xml_parser_create_ns? + $this->parser = xml_parser_create($this->xml_encoding); + // Set the options for parsing the XML data. + //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element','end_element'); + xml_set_character_data_handler($this->parser,'character_data'); + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $err = sprintf('XML error parsing SOAP payload on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser))); + $this->debug($err); + $this->debug("XML payload:\n" . $xml); + $this->setError($err); + } else { + $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); + // get final value + $this->soapresponse = $this->message[$this->root_struct]['result']; + // get header value: no, because this is documented as XML string +// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ +// $this->responseHeaders = $this->message[$this->root_header]['result']; +// } + // resolve hrefs/ids + if(sizeof($this->multirefs) > 0){ + foreach($this->multirefs as $id => $hrefs){ + $this->debug('resolving multirefs for id: '.$id); + $idVal = $this->buildVal($this->ids[$id]); + if (is_array($idVal) && isset($idVal['!id'])) { + unset($idVal['!id']); + } + foreach($hrefs as $refPos => $ref){ + $this->debug('resolving href at pos '.$refPos); + $this->multirefs[$id][$refPos] = $idVal; + } + } + } + } + xml_parser_free($this->parser); + } else { + $this->debug('xml was empty, didn\'t parse!'); + $this->setError('xml was empty, didn\'t parse!'); + } + } + + /** + * start-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @param array $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) { + // position in a total number of elements, starting from 0 + // update class level pos + $pos = $this->position++; + // and set mine + $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); + // depth = how many levels removed from root? + // set mine as current global depth and increment global depth value + $this->message[$pos]['depth'] = $this->depth++; + + // else add self as child to whoever the current parent is + if($pos != 0){ + $this->message[$this->parent]['children'] .= '|'.$pos; + } + // set my parent + $this->message[$pos]['parent'] = $this->parent; + // set self as current parent + $this->parent = $pos; + // set self as current value for this depth + $this->depth_array[$this->depth] = $pos; + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + // set status + if($name == 'Envelope'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->root_header = $pos; + $this->status = 'header'; + } elseif($name == 'Body'){ + $this->status = 'body'; + $this->body_position = $pos; + // set method + } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->message[$pos]['type'] = 'struct'; + $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); + } + // set my status + $this->message[$pos]['status'] = $this->status; + // set name + $this->message[$pos]['name'] = htmlspecialchars($name); + // set attrs + $this->message[$pos]['attrs'] = $attrs; + + // loop through atts, logging ns and type declarations + $attstr = ''; + foreach($attrs as $key => $value){ + $key_prefix = $this->getPrefix($key); + $key_localpart = $this->getLocalPart($key); + // if ns declarations, add to class level array of valid namespaces + if($key_prefix == 'xmlns'){ + if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ + $this->XMLSchemaVersion = $value; + $this->namespaces['xsd'] = $this->XMLSchemaVersion; + $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; + } + $this->namespaces[$key_localpart] = $value; + // set method namespace + if($name == $this->root_struct_name){ + $this->methodNamespace = $value; + } + // if it's a type declaration, set type + } elseif($key_localpart == 'type'){ + $value_prefix = $this->getPrefix($value); + $value_localpart = $this->getLocalPart($value); + $this->message[$pos]['type'] = $value_localpart; + $this->message[$pos]['typePrefix'] = $value_prefix; + if(isset($this->namespaces[$value_prefix])){ + $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; + } else if(isset($attrs['xmlns:'.$value_prefix])) { + $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; + } + // should do something here with the namespace of specified type? + } elseif($key_localpart == 'arrayType'){ + $this->message[$pos]['type'] = 'array'; + /* do arrayType ereg here + [1] arrayTypeValue ::= atype asize + [2] atype ::= QName rank* + [3] rank ::= '[' (',')* ']' + [4] asize ::= '[' length~ ']' + [5] length ::= nextDimension* Digit+ + [6] nextDimension ::= Digit+ ',' + */ + $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; + if(ereg($expr,$value,$regs)){ + $this->message[$pos]['typePrefix'] = $regs[1]; + $this->message[$pos]['arrayTypePrefix'] = $regs[1]; + if (isset($this->namespaces[$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; + } else if (isset($attrs['xmlns:'.$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; + } + $this->message[$pos]['arrayType'] = $regs[2]; + $this->message[$pos]['arraySize'] = $regs[3]; + $this->message[$pos]['arrayCols'] = $regs[4]; + } + // specifies nil value (or not) + } elseif ($key_localpart == 'nil'){ + $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); + // some other attribute + } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { + $this->message[$pos]['xattrs']['!' . $key] = $value; + } + + if ($key == 'xmlns') { + $this->default_namespace = $value; + } + // log id + if($key == 'id'){ + $this->ids[$value] = $pos; + } + // root + if($key_localpart == 'root' && $value == 1){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->debug("found root struct $this->root_struct_name, pos $pos"); + } + // for doclit + $attstr .= " $key=\"$value\""; + } + // get namespace - must be done after namespace atts are processed + if(isset($prefix)){ + $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; + $this->default_namespace = $this->namespaces[$prefix]; + } else { + $this->message[$pos]['namespace'] = $this->default_namespace; + } + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } elseif($this->root_struct_name != ''){ + $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } + + /** + * end-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name) { + // position of current element is equal to the last value left in depth_array for my depth + $pos = $this->depth_array[$this->depth--]; + + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + + // build to native type + if(isset($this->body_position) && $pos > $this->body_position){ + // deal w/ multirefs + if(isset($this->message[$pos]['attrs']['href'])){ + // get id + $id = substr($this->message[$pos]['attrs']['href'],1); + // add placeholder to href array + $this->multirefs[$id][$pos] = 'placeholder'; + // add set a reference to it as the result value + $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; + // build complexType values + } elseif($this->message[$pos]['children'] != ''){ + // if result has already been generated (struct/array) + if(!isset($this->message[$pos]['result'])){ + $this->message[$pos]['result'] = $this->buildVal($pos); + } + // build complexType values of attributes and possibly simpleContent + } elseif (isset($this->message[$pos]['xattrs'])) { + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + if (isset($this->message[$pos]['type'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; + } + } + } + $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; + // set value of simpleType (or nil complexType) + } else { + //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['type'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['result'] = $this->message[$pos]['cdata']; + } + } + + /* add value to parent's result, if parent is struct/array + $parent = $this->message[$pos]['parent']; + if($this->message[$parent]['type'] != 'map'){ + if(strtolower($this->message[$parent]['type']) == 'array'){ + $this->message[$parent]['result'][] = $this->message[$pos]['result']; + } else { + $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; + } + } + */ + } + } + + // for doclit + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; + } + } elseif($pos >= $this->root_struct){ + $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; + } + // switch status + if($pos == $this->root_struct){ + $this->status = 'body'; + $this->root_struct_namespace = $this->message[$pos]['namespace']; + } elseif($name == 'Body'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->status = 'envelope'; + } elseif($name == 'Envelope'){ + // + } + // set parent back to my parent + $this->parent = $this->message[$pos]['parent']; + } + + /** + * element content handler + * + * @param resource $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data){ + $pos = $this->depth_array[$this->depth]; + if ($this->xml_encoding=='UTF-8'){ + // TODO: add an option to disable this for folks who want + // raw UTF-8 that, e.g., might not map to iso-8859-1 + // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); + if($this->decode_utf8){ + $data = utf8_decode($data); + } + } + $this->message[$pos]['cdata'] .= $data; + // for doclit + if($this->status == 'header'){ + $this->responseHeaders .= $data; + } else { + $this->document .= $data; + } + } + + /** + * get the parsed message + * + * @return mixed + * @access public + */ + function get_response(){ + return $this->soapresponse; + } + + /** + * get the parsed headers + * + * @return string XML or empty if no headers + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * decodes simple types into PHP variables + * + * @param string $value value to decode + * @param string $type XML type to decode + * @param string $typens XML type namespace to decode + * @return mixed PHP value + * @access private + */ + function decodeSimple($value, $type, $typens) { + // TODO: use the namespace! + if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { + return (string) $value; + } + if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { + return (int) $value; + } + if ($type == 'float' || $type == 'double' || $type == 'decimal') { + return (double) $value; + } + if ($type == 'boolean') { + if (strtolower($value) == 'false' || strtolower($value) == 'f') { + return false; + } + return (boolean) $value; + } + if ($type == 'base64' || $type == 'base64Binary') { + $this->debug('Decode base64 value'); + return base64_decode($value); + } + // obscure numeric types + if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' + || $type == 'nonNegativeInteger' || $type == 'positiveInteger' + || $type == 'unsignedInt' + || $type == 'unsignedShort' || $type == 'unsignedByte') { + return (int) $value; + } + // bogus: parser treats array with no elements as a simple type + if ($type == 'array') { + return array(); + } + // everything else + return (string) $value; + } + + /** + * builds response structures for compound values (arrays/structs) + * and scalars + * + * @param integer $pos position in node tree + * @return mixed PHP value + * @access private + */ + function buildVal($pos){ + if(!isset($this->message[$pos]['type'])){ + $this->message[$pos]['type'] = ''; + } + $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); + // if there are children... + if($this->message[$pos]['children'] != ''){ + $this->debug('in buildVal, there are children'); + $children = explode('|',$this->message[$pos]['children']); + array_shift($children); // knock off empty + // md array + if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ + $r=0; // rowcount + $c=0; // colcount + foreach($children as $child_pos){ + $this->debug("in buildVal, got an MD array element: $r, $c"); + $params[$r][] = $this->message[$child_pos]['result']; + $c++; + if($c == $this->message[$pos]['arrayCols']){ + $c = 0; + $r++; + } + } + // array + } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ + $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $params[] = &$this->message[$child_pos]['result']; + } + // apache Map type: java hashtable + } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ + $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $kv = explode("|",$this->message[$child_pos]['children']); + $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; + } + // generic compound type + //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { + } else { + // Apache Vector type: treat as an array + $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); + if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { + $notstruct = 1; + } else { + $notstruct = 0; + } + // + foreach($children as $child_pos){ + if($notstruct){ + $params[] = &$this->message[$child_pos]['result']; + } else { + if (isset($params[$this->message[$child_pos]['name']])) { + // de-serialize repeated element name into an array + if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { + $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); + } + $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; + } else { + $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; + } + } + } + } + if (isset($this->message[$pos]['xattrs'])) { + $this->debug('in buildVal, handling attributes'); + foreach ($this->message[$pos]['xattrs'] as $n => $v) { + $params[$n] = $v; + } + } + // handle simpleContent + if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + $this->debug('in buildVal, handling simpleContent'); + if (isset($this->message[$pos]['type'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $params['!'] = $this->message[$pos]['cdata']; + } + } + } + return is_array($params) ? $params : array(); + } else { + $this->debug('in buildVal, no children, building scalar'); + $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; + if (isset($this->message[$pos]['type'])) { + return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } + return $this->message[$pos]['cdata']; + } + } +} + + + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.soap_server.php b/htdocs/includes/nusoap/lib/class.soap_server.php index 88afe2059af6e3329d70380f1cd0d13bc0a7ac1e..4033d32513423c5f20a72676718379f6d2e60bc7 100644 --- a/htdocs/includes/nusoap/lib/class.soap_server.php +++ b/htdocs/includes/nusoap/lib/class.soap_server.php @@ -1,1038 +1,1038 @@ -<?php - - - - -/** -* -* soap_server allows the user to create a SOAP server -* that is capable of receiving messages and returning responses -* -* NOTE: WSDL functionality is experimental -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_server extends nusoap_base { - /** - * HTTP headers of request - * @var array - * @access private - */ - var $headers = array(); - /** - * HTTP request - * @var string - * @access private - */ - var $request = ''; - /** - * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) - * @var string - * @access public - */ - var $requestHeaders = ''; - /** - * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) - * @var string - * @access public - */ - var $document = ''; - /** - * SOAP payload for request (text) - * @var string - * @access public - */ - var $requestSOAP = ''; - /** - * requested method namespace URI - * @var string - * @access private - */ - var $methodURI = ''; - /** - * name of method requested - * @var string - * @access private - */ - var $methodname = ''; - /** - * method parameters from request - * @var array - * @access private - */ - var $methodparams = array(); - /** - * SOAP Action from request - * @var string - * @access private - */ - var $SOAPAction = ''; - /** - * character set encoding of incoming (request) messages - * @var string - * @access public - */ - var $xml_encoding = ''; - /** - * toggles whether the parser decodes element content w/ utf8_decode() - * @var boolean - * @access public - */ - var $decode_utf8 = true; - - /** - * HTTP headers of response - * @var array - * @access public - */ - var $outgoing_headers = array(); - /** - * HTTP response - * @var string - * @access private - */ - var $response = ''; - /** - * SOAP headers for response (text) - * @var string - * @access public - */ - var $responseHeaders = ''; - /** - * SOAP payload for response (text) - * @var string - * @access private - */ - var $responseSOAP = ''; - /** - * method return value to place in response - * @var mixed - * @access private - */ - var $methodreturn = false; - /** - * whether $methodreturn is a string of literal XML - * @var boolean - * @access public - */ - var $methodreturnisliteralxml = false; - /** - * SOAP fault for response (or false) - * @var mixed - * @access private - */ - var $fault = false; - /** - * text indication of result (for debugging) - * @var string - * @access private - */ - var $result = 'successful'; - - /** - * assoc array of operations => opData; operations are added by the register() - * method or by parsing an external WSDL definition - * @var array - * @access private - */ - var $operations = array(); - /** - * wsdl instance (if one) - * @var mixed - * @access private - */ - var $wsdl = false; - /** - * URL for WSDL (if one) - * @var mixed - * @access private - */ - var $externalWSDLURL = false; - /** - * whether to append debug to response as XML comment - * @var boolean - * @access public - */ - var $debug_flag = false; - - - /** - * constructor - * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. - * - * @param mixed $wsdl file path or URL (string), or wsdl instance (object) - * @access public - */ - function soap_server($wsdl=false){ - parent::nusoap_base(); - // turn on debugging? - global $debug; - global $HTTP_SERVER_VARS; - - if (isset($_SERVER)) { - $this->debug("_SERVER is defined:"); - $this->appendDebug($this->varDump($_SERVER)); - } elseif (isset($HTTP_SERVER_VARS)) { - $this->debug("HTTP_SERVER_VARS is defined:"); - $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); - } else { - $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); - } - - if (isset($debug)) { - $this->debug("In soap_server, set debug_flag=$debug based on global flag"); - $this->debug_flag = $debug; - } elseif (isset($_SERVER['QUERY_STRING'])) { - $qs = explode('&', $_SERVER['QUERY_STRING']); - foreach ($qs as $v) { - if (substr($v, 0, 6) == 'debug=') { - $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); - $this->debug_flag = substr($v, 6); - } - } - } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { - $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); - foreach ($qs as $v) { - if (substr($v, 0, 6) == 'debug=') { - $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); - $this->debug_flag = substr($v, 6); - } - } - } - - // wsdl - if($wsdl){ - $this->debug("In soap_server, WSDL is specified"); - if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { - $this->wsdl = $wsdl; - $this->externalWSDLURL = $this->wsdl->wsdl; - $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); - } else { - $this->debug('Create wsdl from ' . $wsdl); - $this->wsdl = new wsdl($wsdl); - $this->externalWSDLURL = $wsdl; - } - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - if($err = $this->wsdl->getError()){ - die('WSDL ERROR: '.$err); - } - } - } - - /** - * processes request and returns response - * - * @param string $data usually is the value of $HTTP_RAW_POST_DATA - * @access public - */ - function service($data){ - global $HTTP_SERVER_VARS; - - if (isset($_SERVER['QUERY_STRING'])) { - $qs = $_SERVER['QUERY_STRING']; - } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { - $qs = $HTTP_SERVER_VARS['QUERY_STRING']; - } else { - $qs = ''; - } - $this->debug("In service, query string=$qs"); - - if (ereg('wsdl', $qs) ){ - $this->debug("In service, this is a request for WSDL"); - if($this->externalWSDLURL){ - if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL - header('Location: '.$this->externalWSDLURL); - } else { // assume file - header("Content-Type: text/xml\r\n"); - $fp = fopen($this->externalWSDLURL, 'r'); - fpassthru($fp); - } - } elseif ($this->wsdl) { - header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); - print $this->wsdl->serialize($this->debug_flag); - if ($this->debug_flag) { - $this->debug('wsdl:'); - $this->appendDebug($this->varDump($this->wsdl)); - print $this->getDebugAsXMLComment(); - } - } else { - header("Content-Type: text/html; charset=ISO-8859-1\r\n"); - print "This service does not provide WSDL"; - } - } elseif ($data == '' && $this->wsdl) { - $this->debug("In service, there is no data, so return Web description"); - print $this->wsdl->webDescription(); - } else { - $this->debug("In service, invoke the request"); - $this->parse_request($data); - if (! $this->fault) { - $this->invoke_method(); - } - if (! $this->fault) { - $this->serialize_return(); - } - $this->send_response(); - } - } - - /** - * parses HTTP request headers. - * - * The following fields are set by this function (when successful) - * - * headers - * request - * xml_encoding - * SOAPAction - * - * @access private - */ - function parse_http_headers() { - global $HTTP_SERVER_VARS; - - $this->request = ''; - $this->SOAPAction = ''; - if(function_exists('getallheaders')){ - $this->debug("In parse_http_headers, use getallheaders"); - $headers = getallheaders(); - foreach($headers as $k=>$v){ - $k = strtolower($k); - $this->headers[$k] = $v; - $this->request .= "$k: $v\r\n"; - $this->debug("$k: $v"); - } - // get SOAPAction header - if(isset($this->headers['soapaction'])){ - $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); - } - // get the character encoding of the incoming request - if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ - $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); - if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - } elseif(isset($_SERVER) && is_array($_SERVER)){ - $this->debug("In parse_http_headers, use _SERVER"); - foreach ($_SERVER as $k => $v) { - if (substr($k, 0, 5) == 'HTTP_') { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); - } else { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); - } - if ($k == 'soapaction') { - // get SOAPAction header - $k = 'SOAPAction'; - $v = str_replace('"', '', $v); - $v = str_replace('\\', '', $v); - $this->SOAPAction = $v; - } else if ($k == 'content-type') { - // get the character encoding of the incoming request - if (strpos($v, '=')) { - $enc = substr(strstr($v, '='), 1); - $enc = str_replace('"', '', $enc); - $enc = str_replace('\\', '', $enc); - if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - } - $this->headers[$k] = $v; - $this->request .= "$k: $v\r\n"; - $this->debug("$k: $v"); - } - } elseif (is_array($HTTP_SERVER_VARS)) { - $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); - foreach ($HTTP_SERVER_VARS as $k => $v) { - if (substr($k, 0, 5) == 'HTTP_') { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); - } else { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); - } - if ($k == 'soapaction') { - // get SOAPAction header - $k = 'SOAPAction'; - $v = str_replace('"', '', $v); - $v = str_replace('\\', '', $v); - $this->SOAPAction = $v; - } else if ($k == 'content-type') { - // get the character encoding of the incoming request - if (strpos($v, '=')) { - $enc = substr(strstr($v, '='), 1); - $enc = str_replace('"', '', $enc); - $enc = str_replace('\\', '', $enc); - if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - } - $this->headers[$k] = $v; - $this->request .= "$k: $v\r\n"; - $this->debug("$k: $v"); - } - } else { - $this->debug("In parse_http_headers, HTTP headers not accessible"); - $this->setError("HTTP headers not accessible"); - } - } - - /** - * parses a request - * - * The following fields are set by this function (when successful) - * - * headers - * request - * xml_encoding - * SOAPAction - * request - * requestSOAP - * methodURI - * methodname - * methodparams - * requestHeaders - * document - * - * This sets the fault field on error - * - * @param string $data XML string - * @access private - */ - function parse_request($data='') { - $this->debug('entering parse_request()'); - $this->parse_http_headers(); - $this->debug('got character encoding: '.$this->xml_encoding); - // uncompress if necessary - if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { - $this->debug('got content encoding: ' . $this->headers['content-encoding']); - if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { - // if decoding works, use it. else assume data wasn't gzencoded - if (function_exists('gzuncompress')) { - if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { - $data = $degzdata; - } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { - $data = $degzdata; - } else { - $this->fault('Client', 'Errors occurred when trying to decode the data'); - return; - } - } else { - $this->fault('Client', 'This Server does not support compressed data'); - return; - } - } - } - $this->request .= "\r\n".$data; - $data = $this->parseRequest($this->headers, $data); - $this->requestSOAP = $data; - $this->debug('leaving parse_request'); - } - - /** - * invokes a PHP function for the requested SOAP method - * - * The following fields are set by this function (when successful) - * - * methodreturn - * - * Note that the PHP function that is called may also set the following - * fields to affect the response sent to the client - * - * responseHeaders - * outgoing_headers - * - * This sets the fault field on error - * - * @access private - */ - function invoke_method() { - $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); - - if ($this->wsdl) { - if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { - $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); - $this->appendDebug('opData=' . $this->varDump($this->opData)); - } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { - // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element - $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); - $this->appendDebug('opData=' . $this->varDump($this->opData)); - $this->methodname = $this->opData['name']; - } else { - $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); - $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); - return; - } - } else { - $this->debug('in invoke_method, no WSDL to validate method'); - } - - // if a . is present in $this->methodname, we see if there is a class in scope, - // which could be referred to. We will also distinguish between two deliminators, - // to allow methods to be called a the class or an instance - $class = ''; - $method = ''; - if (strpos($this->methodname, '..') > 0) { - $delim = '..'; - } else if (strpos($this->methodname, '.') > 0) { - $delim = '.'; - } else { - $delim = ''; - } - - if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && - class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { - // get the class and method name - $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); - $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); - $this->debug("in invoke_method, class=$class method=$method delim=$delim"); - } - - // does method exist? - if ($class == '') { - if (!function_exists($this->methodname)) { - $this->debug("in invoke_method, function '$this->methodname' not found!"); - $this->result = 'fault: method not found'; - $this->fault('Client',"method '$this->methodname' not defined in service"); - return; - } - } else { - $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; - if (!in_array($method_to_compare, get_class_methods($class))) { - $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); - $this->result = 'fault: method not found'; - $this->fault('Client',"method '$this->methodname' not defined in service"); - return; - } - } - - // evaluate message, getting back parameters - // verify that request parameters match the method's signature - if(! $this->verify_method($this->methodname,$this->methodparams)){ - // debug - $this->debug('ERROR: request not verified against method signature'); - $this->result = 'fault: request failed validation against method signature'; - // return fault - $this->fault('Client',"Operation '$this->methodname' not defined in service."); - return; - } - - // if there are parameters to pass - $this->debug('in invoke_method, params:'); - $this->appendDebug($this->varDump($this->methodparams)); - $this->debug("in invoke_method, calling '$this->methodname'"); - if (!function_exists('call_user_func_array')) { - if ($class == '') { - $this->debug('in invoke_method, calling function using eval()'); - $funcCall = "\$this->methodreturn = $this->methodname("; - } else { - if ($delim == '..') { - $this->debug('in invoke_method, calling class method using eval()'); - $funcCall = "\$this->methodreturn = ".$class."::".$method."("; - } else { - $this->debug('in invoke_method, calling instance method using eval()'); - // generate unique instance name - $instname = "\$inst_".time(); - $funcCall = $instname." = new ".$class."(); "; - $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; - } - } - if ($this->methodparams) { - foreach ($this->methodparams as $param) { - if (is_array($param)) { - $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); - return; - } - $funcCall .= "\"$param\","; - } - $funcCall = substr($funcCall, 0, -1); - } - $funcCall .= ');'; - $this->debug('in invoke_method, function call: '.$funcCall); - @eval($funcCall); - } else { - if ($class == '') { - $this->debug('in invoke_method, calling function using call_user_func_array()'); - $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() - } elseif ($delim == '..') { - $this->debug('in invoke_method, calling class method using call_user_func_array()'); - $call_arg = array ($class, $method); - } else { - $this->debug('in invoke_method, calling instance method using call_user_func_array()'); - $instance = new $class (); - $call_arg = array(&$instance, $method); - } - $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); - } - $this->debug('in invoke_method, methodreturn:'); - $this->appendDebug($this->varDump($this->methodreturn)); - $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); - } - - /** - * serializes the return value from a PHP function into a full SOAP Envelope - * - * The following fields are set by this function (when successful) - * - * responseSOAP - * - * This sets the fault field on error - * - * @access private - */ - function serialize_return() { - $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); - // if fault - if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) { - $this->debug('got a fault object from method'); - $this->fault = $this->methodreturn; - return; - } elseif ($this->methodreturnisliteralxml) { - $return_val = $this->methodreturn; - // returned value(s) - } else { - $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); - $this->debug('serializing return value'); - if($this->wsdl){ - // weak attempt at supporting multiple output params - if(sizeof($this->opData['output']['parts']) > 1){ - $opParams = $this->methodreturn; - } else { - // TODO: is this really necessary? - $opParams = array($this->methodreturn); - } - $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - if($errstr = $this->wsdl->getError()){ - $this->debug('got wsdl error: '.$errstr); - $this->fault('Server', 'unable to serialize result'); - return; - } - } else { - if (isset($this->methodreturn)) { - $return_val = $this->serialize_val($this->methodreturn, 'return'); - } else { - $return_val = ''; - $this->debug('in absence of WSDL, assume void return for backward compatibility'); - } - } - } - $this->debug('return value:'); - $this->appendDebug($this->varDump($return_val)); - - $this->debug('serializing response'); - if ($this->wsdl) { - $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); - if ($this->opData['style'] == 'rpc') { - $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); - if ($this->opData['output']['use'] == 'literal') { - $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>"; - } else { - $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; - } - } else { - $this->debug('style is not rpc for serialization: assume document'); - $payload = $return_val; - } - } else { - $this->debug('do not have WSDL for serialization: assume rpc/encoded'); - $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; - } - $this->result = 'successful'; - if($this->wsdl){ - //if($this->debug_flag){ - $this->appendDebug($this->wsdl->getDebug()); - // } - if (isset($opData['output']['encodingStyle'])) { - $encodingStyle = $opData['output']['encodingStyle']; - } else { - $encodingStyle = ''; - } - // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. - $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); - } else { - $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); - } - $this->debug("Leaving serialize_return"); - } - - /** - * sends an HTTP response - * - * The following fields are set by this function (when successful) - * - * outgoing_headers - * response - * - * @access private - */ - function send_response() { - $this->debug('Enter send_response'); - if ($this->fault) { - $payload = $this->fault->serialize(); - $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; - $this->outgoing_headers[] = "Status: 500 Internal Server Error"; - } else { - $payload = $this->responseSOAP; - // Some combinations of PHP+Web server allow the Status - // to come through as a header. Since OK is the default - // just do nothing. - // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; - // $this->outgoing_headers[] = "Status: 200 OK"; - } - // add debug data if in debug mode - if(isset($this->debug_flag) && $this->debug_flag){ - $payload .= $this->getDebugAsXMLComment(); - } - $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; - ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); - $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; - // Let the Web server decide about this - //$this->outgoing_headers[] = "Connection: Close\r\n"; - $payload = $this->getHTTPBody($payload); - $type = $this->getHTTPContentType(); - $charset = $this->getHTTPContentTypeCharset(); - $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); - //begin code to compress payload - by John - // NOTE: there is no way to know whether the Web server will also compress - // this data. - if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { - if (strstr($this->headers['accept-encoding'], 'gzip')) { - if (function_exists('gzencode')) { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content being gzipped -->"; - } - $this->outgoing_headers[] = "Content-Encoding: gzip"; - $payload = gzencode($payload); - } else { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content will not be gzipped: no gzencode -->"; - } - } - } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { - // Note: MSIE requires gzdeflate output (no Zlib header and checksum), - // instead of gzcompress output, - // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) - if (function_exists('gzdeflate')) { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content being deflated -->"; - } - $this->outgoing_headers[] = "Content-Encoding: deflate"; - $payload = gzdeflate($payload); - } else { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content will not be deflated: no gzcompress -->"; - } - } - } - } - //end code - $this->outgoing_headers[] = "Content-Length: ".strlen($payload); - reset($this->outgoing_headers); - foreach($this->outgoing_headers as $hdr){ - header($hdr, false); - } - print $payload; - $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; - } - - /** - * takes the value that was created by parsing the request - * and compares to the method's signature, if available. - * - * @param string $operation The operation to be invoked - * @param array $request The array of parameter values - * @return boolean Whether the operation was found - * @access private - */ - function verify_method($operation,$request){ - if(isset($this->wsdl) && is_object($this->wsdl)){ - if($this->wsdl->getOperationData($operation)){ - return true; - } - } elseif(isset($this->operations[$operation])){ - return true; - } - return false; - } - - /** - * processes SOAP message received from client - * - * @param array $headers The HTTP headers - * @param string $data unprocessed request data from client - * @return mixed value of the message, decoded into a PHP type - * @access private - */ - function parseRequest($headers, $data) { - $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); - if (!strstr($headers['content-type'], 'text/xml')) { - $this->setError('Request not of type text/xml'); - return false; - } - if (strpos($headers['content-type'], '=')) { - $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); - $this->debug('Got response encoding: ' . $enc); - if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); - // parse response, get soap parser obj - $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8); - // parser debug - $this->debug("parser debug: \n".$parser->getDebug()); - // if fault occurred during message parsing - if($err = $parser->getError()){ - $this->result = 'fault: error in msg parsing: '.$err; - $this->fault('Client',"error in msg parsing:\n".$err); - // else successfully parsed request into soapval object - } else { - // get/set methodname - $this->methodURI = $parser->root_struct_namespace; - $this->methodname = $parser->root_struct_name; - $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); - $this->debug('calling parser->get_response()'); - $this->methodparams = $parser->get_response(); - // get SOAP headers - $this->requestHeaders = $parser->getHeaders(); - // add document for doclit support - $this->document = $parser->document; - } - } - - /** - * gets the HTTP body for the current response. - * - * @param string $soapmsg The SOAP payload - * @return string The HTTP body, which includes the SOAP payload - * @access private - */ - function getHTTPBody($soapmsg) { - return $soapmsg; - } - - /** - * gets the HTTP content type for the current response. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type for the current response. - * @access private - */ - function getHTTPContentType() { - return 'text/xml'; - } - - /** - * gets the HTTP content type charset for the current response. - * returns false for non-text content types. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type charset for the current response. - * @access private - */ - function getHTTPContentTypeCharset() { - return $this->soap_defencoding; - } - - /** - * add a method to the dispatch map (this has been replaced by the register method) - * - * @param string $methodname - * @param string $in array of input values - * @param string $out array of output values - * @access public - * @deprecated - */ - function add_to_map($methodname,$in,$out){ - $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); - } - - /** - * register a service function with the server - * - * @param string $name the name of the PHP function, class.method or class..method - * @param array $in assoc array of input values: key = param name, value = param type - * @param array $out assoc array of output values: key = param name, value = param type - * @param mixed $namespace the element namespace for the method or false - * @param mixed $soapaction the soapaction for the method or false - * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically - * @param mixed $use optional (encoded|literal) or false - * @param string $documentation optional Description to include in WSDL - * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) - * @access public - */ - function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ - global $HTTP_SERVER_VARS; - - if($this->externalWSDLURL){ - die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); - } - if (! $name) { - die('You must specify a name when you register an operation'); - } - if (!is_array($in)) { - die('You must provide an array for operation inputs'); - } - if (!is_array($out)) { - die('You must provide an array for operation outputs'); - } - if(false == $namespace) { - } - if(false == $soapaction) { - if (isset($_SERVER)) { - $SERVER_NAME = $_SERVER['SERVER_NAME']; - $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; - } elseif (isset($HTTP_SERVER_VARS)) { - $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; - $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; - } else { - $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); - } - $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; - } - if(false == $style) { - $style = "rpc"; - } - if(false == $use) { - $use = "encoded"; - } - if ($use == 'encoded' && $encodingStyle = '') { - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - } - - $this->operations[$name] = array( - 'name' => $name, - 'in' => $in, - 'out' => $out, - 'namespace' => $namespace, - 'soapaction' => $soapaction, - 'style' => $style); - if($this->wsdl){ - $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); - } - return true; - } - - /** - * Specify a fault to be returned to the client. - * This also acts as a flag to the server that a fault has occured. - * - * @param string $faultcode - * @param string $faultstring - * @param string $faultactor - * @param string $faultdetail - * @access public - */ - function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ - if ($faultdetail == '' && $this->debug_flag) { - $faultdetail = $this->getDebug(); - } - $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); - $this->fault->soap_defencoding = $this->soap_defencoding; - } - - /** - * Sets up wsdl object. - * Acts as a flag to enable internal WSDL generation - * - * @param string $serviceName, name of the service - * @param mixed $namespace optional 'tns' service namespace or false - * @param mixed $endpoint optional URL of service endpoint or false - * @param string $style optional (rpc|document) WSDL style (also specified by operation) - * @param string $transport optional SOAP transport - * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false - */ - function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) - { - global $HTTP_SERVER_VARS; - - if (isset($_SERVER)) { - $SERVER_NAME = $_SERVER['SERVER_NAME']; - $SERVER_PORT = $_SERVER['SERVER_PORT']; - $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; - $HTTPS = $_SERVER['HTTPS']; - } elseif (isset($HTTP_SERVER_VARS)) { - $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; - $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; - $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; - $HTTPS = $HTTP_SERVER_VARS['HTTPS']; - } else { - $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); - } - if ($SERVER_PORT == 80) { - $SERVER_PORT = ''; - } else { - $SERVER_PORT = ':' . $SERVER_PORT; - } - if(false == $namespace) { - $namespace = "http://$SERVER_NAME/soap/$serviceName"; - } - - if(false == $endpoint) { - if ($HTTPS == '1' || $HTTPS == 'on') { - $SCHEME = 'https'; - } else { - $SCHEME = 'http'; - } - $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; - } - - if(false == $schemaTargetNamespace) { - $schemaTargetNamespace = $namespace; - } - - $this->wsdl = new wsdl; - $this->wsdl->serviceName = $serviceName; - $this->wsdl->endpoint = $endpoint; - $this->wsdl->namespaces['tns'] = $namespace; - $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; - $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; - if ($schemaTargetNamespace != $namespace) { - $this->wsdl->namespaces['types'] = $schemaTargetNamespace; - } - $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); - $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; - $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); - $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); - $this->wsdl->bindings[$serviceName.'Binding'] = array( - 'name'=>$serviceName.'Binding', - 'style'=>$style, - 'transport'=>$transport, - 'portType'=>$serviceName.'PortType'); - $this->wsdl->ports[$serviceName.'Port'] = array( - 'binding'=>$serviceName.'Binding', - 'location'=>$endpoint, - 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); - } -} - - - - +<?php + + + + +/** +* +* soap_server allows the user to create a SOAP server +* that is capable of receiving messages and returning responses +* +* NOTE: WSDL functionality is experimental +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_server extends nusoap_base { + /** + * HTTP headers of request + * @var array + * @access private + */ + var $headers = array(); + /** + * HTTP request + * @var string + * @access private + */ + var $request = ''; + /** + * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $requestHeaders = ''; + /** + * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $document = ''; + /** + * SOAP payload for request (text) + * @var string + * @access public + */ + var $requestSOAP = ''; + /** + * requested method namespace URI + * @var string + * @access private + */ + var $methodURI = ''; + /** + * name of method requested + * @var string + * @access private + */ + var $methodname = ''; + /** + * method parameters from request + * @var array + * @access private + */ + var $methodparams = array(); + /** + * SOAP Action from request + * @var string + * @access private + */ + var $SOAPAction = ''; + /** + * character set encoding of incoming (request) messages + * @var string + * @access public + */ + var $xml_encoding = ''; + /** + * toggles whether the parser decodes element content w/ utf8_decode() + * @var boolean + * @access public + */ + var $decode_utf8 = true; + + /** + * HTTP headers of response + * @var array + * @access public + */ + var $outgoing_headers = array(); + /** + * HTTP response + * @var string + * @access private + */ + var $response = ''; + /** + * SOAP headers for response (text) + * @var string + * @access public + */ + var $responseHeaders = ''; + /** + * SOAP payload for response (text) + * @var string + * @access private + */ + var $responseSOAP = ''; + /** + * method return value to place in response + * @var mixed + * @access private + */ + var $methodreturn = false; + /** + * whether $methodreturn is a string of literal XML + * @var boolean + * @access public + */ + var $methodreturnisliteralxml = false; + /** + * SOAP fault for response (or false) + * @var mixed + * @access private + */ + var $fault = false; + /** + * text indication of result (for debugging) + * @var string + * @access private + */ + var $result = 'successful'; + + /** + * assoc array of operations => opData; operations are added by the register() + * method or by parsing an external WSDL definition + * @var array + * @access private + */ + var $operations = array(); + /** + * wsdl instance (if one) + * @var mixed + * @access private + */ + var $wsdl = false; + /** + * URL for WSDL (if one) + * @var mixed + * @access private + */ + var $externalWSDLURL = false; + /** + * whether to append debug to response as XML comment + * @var boolean + * @access public + */ + var $debug_flag = false; + + + /** + * constructor + * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. + * + * @param mixed $wsdl file path or URL (string), or wsdl instance (object) + * @access public + */ + function soap_server($wsdl=false){ + parent::nusoap_base(); + // turn on debugging? + global $debug; + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $this->debug("_SERVER is defined:"); + $this->appendDebug($this->varDump($_SERVER)); + } elseif (isset($HTTP_SERVER_VARS)) { + $this->debug("HTTP_SERVER_VARS is defined:"); + $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); + } else { + $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); + } + + if (isset($debug)) { + $this->debug("In soap_server, set debug_flag=$debug based on global flag"); + $this->debug_flag = $debug; + } elseif (isset($_SERVER['QUERY_STRING'])) { + $qs = explode('&', $_SERVER['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); + $this->debug_flag = substr($v, 6); + } + } + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); + $this->debug_flag = substr($v, 6); + } + } + } + + // wsdl + if($wsdl){ + $this->debug("In soap_server, WSDL is specified"); + if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { + $this->wsdl = $wsdl; + $this->externalWSDLURL = $this->wsdl->wsdl; + $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); + } else { + $this->debug('Create wsdl from ' . $wsdl); + $this->wsdl = new wsdl($wsdl); + $this->externalWSDLURL = $wsdl; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($err = $this->wsdl->getError()){ + die('WSDL ERROR: '.$err); + } + } + } + + /** + * processes request and returns response + * + * @param string $data usually is the value of $HTTP_RAW_POST_DATA + * @access public + */ + function service($data){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER['QUERY_STRING'])) { + $qs = $_SERVER['QUERY_STRING']; + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = $HTTP_SERVER_VARS['QUERY_STRING']; + } else { + $qs = ''; + } + $this->debug("In service, query string=$qs"); + + if (ereg('wsdl', $qs) ){ + $this->debug("In service, this is a request for WSDL"); + if($this->externalWSDLURL){ + if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL + header('Location: '.$this->externalWSDLURL); + } else { // assume file + header("Content-Type: text/xml\r\n"); + $fp = fopen($this->externalWSDLURL, 'r'); + fpassthru($fp); + } + } elseif ($this->wsdl) { + header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); + print $this->wsdl->serialize($this->debug_flag); + if ($this->debug_flag) { + $this->debug('wsdl:'); + $this->appendDebug($this->varDump($this->wsdl)); + print $this->getDebugAsXMLComment(); + } + } else { + header("Content-Type: text/html; charset=ISO-8859-1\r\n"); + print "This service does not provide WSDL"; + } + } elseif ($data == '' && $this->wsdl) { + $this->debug("In service, there is no data, so return Web description"); + print $this->wsdl->webDescription(); + } else { + $this->debug("In service, invoke the request"); + $this->parse_request($data); + if (! $this->fault) { + $this->invoke_method(); + } + if (! $this->fault) { + $this->serialize_return(); + } + $this->send_response(); + } + } + + /** + * parses HTTP request headers. + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * + * @access private + */ + function parse_http_headers() { + global $HTTP_SERVER_VARS; + + $this->request = ''; + $this->SOAPAction = ''; + if(function_exists('getallheaders')){ + $this->debug("In parse_http_headers, use getallheaders"); + $headers = getallheaders(); + foreach($headers as $k=>$v){ + $k = strtolower($k); + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + // get SOAPAction header + if(isset($this->headers['soapaction'])){ + $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); + } + // get the character encoding of the incoming request + if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ + $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } elseif(isset($_SERVER) && is_array($_SERVER)){ + $this->debug("In parse_http_headers, use _SERVER"); + foreach ($_SERVER as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } elseif (is_array($HTTP_SERVER_VARS)) { + $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); + foreach ($HTTP_SERVER_VARS as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } else { + $this->debug("In parse_http_headers, HTTP headers not accessible"); + $this->setError("HTTP headers not accessible"); + } + } + + /** + * parses a request + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * request + * requestSOAP + * methodURI + * methodname + * methodparams + * requestHeaders + * document + * + * This sets the fault field on error + * + * @param string $data XML string + * @access private + */ + function parse_request($data='') { + $this->debug('entering parse_request()'); + $this->parse_http_headers(); + $this->debug('got character encoding: '.$this->xml_encoding); + // uncompress if necessary + if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { + $this->debug('got content encoding: ' . $this->headers['content-encoding']); + if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { + // if decoding works, use it. else assume data wasn't gzencoded + if (function_exists('gzuncompress')) { + if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { + $data = $degzdata; + } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { + $data = $degzdata; + } else { + $this->fault('Client', 'Errors occurred when trying to decode the data'); + return; + } + } else { + $this->fault('Client', 'This Server does not support compressed data'); + return; + } + } + } + $this->request .= "\r\n".$data; + $data = $this->parseRequest($this->headers, $data); + $this->requestSOAP = $data; + $this->debug('leaving parse_request'); + } + + /** + * invokes a PHP function for the requested SOAP method + * + * The following fields are set by this function (when successful) + * + * methodreturn + * + * Note that the PHP function that is called may also set the following + * fields to affect the response sent to the client + * + * responseHeaders + * outgoing_headers + * + * This sets the fault field on error + * + * @access private + */ + function invoke_method() { + $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); + + if ($this->wsdl) { + if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { + $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { + // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element + $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + $this->methodname = $this->opData['name']; + } else { + $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); + $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); + return; + } + } else { + $this->debug('in invoke_method, no WSDL to validate method'); + } + + // if a . is present in $this->methodname, we see if there is a class in scope, + // which could be referred to. We will also distinguish between two deliminators, + // to allow methods to be called a the class or an instance + $class = ''; + $method = ''; + if (strpos($this->methodname, '..') > 0) { + $delim = '..'; + } else if (strpos($this->methodname, '.') > 0) { + $delim = '.'; + } else { + $delim = ''; + } + + if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && + class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { + // get the class and method name + $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); + $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); + $this->debug("in invoke_method, class=$class method=$method delim=$delim"); + } + + // does method exist? + if ($class == '') { + if (!function_exists($this->methodname)) { + $this->debug("in invoke_method, function '$this->methodname' not found!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } else { + $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; + if (!in_array($method_to_compare, get_class_methods($class))) { + $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } + + // evaluate message, getting back parameters + // verify that request parameters match the method's signature + if(! $this->verify_method($this->methodname,$this->methodparams)){ + // debug + $this->debug('ERROR: request not verified against method signature'); + $this->result = 'fault: request failed validation against method signature'; + // return fault + $this->fault('Client',"Operation '$this->methodname' not defined in service."); + return; + } + + // if there are parameters to pass + $this->debug('in invoke_method, params:'); + $this->appendDebug($this->varDump($this->methodparams)); + $this->debug("in invoke_method, calling '$this->methodname'"); + if (!function_exists('call_user_func_array')) { + if ($class == '') { + $this->debug('in invoke_method, calling function using eval()'); + $funcCall = "\$this->methodreturn = $this->methodname("; + } else { + if ($delim == '..') { + $this->debug('in invoke_method, calling class method using eval()'); + $funcCall = "\$this->methodreturn = ".$class."::".$method."("; + } else { + $this->debug('in invoke_method, calling instance method using eval()'); + // generate unique instance name + $instname = "\$inst_".time(); + $funcCall = $instname." = new ".$class."(); "; + $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; + } + } + if ($this->methodparams) { + foreach ($this->methodparams as $param) { + if (is_array($param)) { + $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); + return; + } + $funcCall .= "\"$param\","; + } + $funcCall = substr($funcCall, 0, -1); + } + $funcCall .= ');'; + $this->debug('in invoke_method, function call: '.$funcCall); + @eval($funcCall); + } else { + if ($class == '') { + $this->debug('in invoke_method, calling function using call_user_func_array()'); + $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() + } elseif ($delim == '..') { + $this->debug('in invoke_method, calling class method using call_user_func_array()'); + $call_arg = array ($class, $method); + } else { + $this->debug('in invoke_method, calling instance method using call_user_func_array()'); + $instance = new $class (); + $call_arg = array(&$instance, $method); + } + $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); + } + $this->debug('in invoke_method, methodreturn:'); + $this->appendDebug($this->varDump($this->methodreturn)); + $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); + } + + /** + * serializes the return value from a PHP function into a full SOAP Envelope + * + * The following fields are set by this function (when successful) + * + * responseSOAP + * + * This sets the fault field on error + * + * @access private + */ + function serialize_return() { + $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); + // if fault + if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) { + $this->debug('got a fault object from method'); + $this->fault = $this->methodreturn; + return; + } elseif ($this->methodreturnisliteralxml) { + $return_val = $this->methodreturn; + // returned value(s) + } else { + $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); + $this->debug('serializing return value'); + if($this->wsdl){ + // weak attempt at supporting multiple output params + if(sizeof($this->opData['output']['parts']) > 1){ + $opParams = $this->methodreturn; + } else { + // TODO: is this really necessary? + $opParams = array($this->methodreturn); + } + $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->fault('Server', 'unable to serialize result'); + return; + } + } else { + if (isset($this->methodreturn)) { + $return_val = $this->serialize_val($this->methodreturn, 'return'); + } else { + $return_val = ''; + $this->debug('in absence of WSDL, assume void return for backward compatibility'); + } + } + } + $this->debug('return value:'); + $this->appendDebug($this->varDump($return_val)); + + $this->debug('serializing response'); + if ($this->wsdl) { + $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); + if ($this->opData['style'] == 'rpc') { + $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); + if ($this->opData['output']['use'] == 'literal') { + $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>"; + } else { + $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; + } + } else { + $this->debug('style is not rpc for serialization: assume document'); + $payload = $return_val; + } + } else { + $this->debug('do not have WSDL for serialization: assume rpc/encoded'); + $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; + } + $this->result = 'successful'; + if($this->wsdl){ + //if($this->debug_flag){ + $this->appendDebug($this->wsdl->getDebug()); + // } + if (isset($opData['output']['encodingStyle'])) { + $encodingStyle = $opData['output']['encodingStyle']; + } else { + $encodingStyle = ''; + } + // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); + } else { + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); + } + $this->debug("Leaving serialize_return"); + } + + /** + * sends an HTTP response + * + * The following fields are set by this function (when successful) + * + * outgoing_headers + * response + * + * @access private + */ + function send_response() { + $this->debug('Enter send_response'); + if ($this->fault) { + $payload = $this->fault->serialize(); + $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; + $this->outgoing_headers[] = "Status: 500 Internal Server Error"; + } else { + $payload = $this->responseSOAP; + // Some combinations of PHP+Web server allow the Status + // to come through as a header. Since OK is the default + // just do nothing. + // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; + // $this->outgoing_headers[] = "Status: 200 OK"; + } + // add debug data if in debug mode + if(isset($this->debug_flag) && $this->debug_flag){ + $payload .= $this->getDebugAsXMLComment(); + } + $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; + // Let the Web server decide about this + //$this->outgoing_headers[] = "Connection: Close\r\n"; + $payload = $this->getHTTPBody($payload); + $type = $this->getHTTPContentType(); + $charset = $this->getHTTPContentTypeCharset(); + $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); + //begin code to compress payload - by John + // NOTE: there is no way to know whether the Web server will also compress + // this data. + if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { + if (strstr($this->headers['accept-encoding'], 'gzip')) { + if (function_exists('gzencode')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content being gzipped -->"; + } + $this->outgoing_headers[] = "Content-Encoding: gzip"; + $payload = gzencode($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content will not be gzipped: no gzencode -->"; + } + } + } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { + // Note: MSIE requires gzdeflate output (no Zlib header and checksum), + // instead of gzcompress output, + // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) + if (function_exists('gzdeflate')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content being deflated -->"; + } + $this->outgoing_headers[] = "Content-Encoding: deflate"; + $payload = gzdeflate($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content will not be deflated: no gzcompress -->"; + } + } + } + } + //end code + $this->outgoing_headers[] = "Content-Length: ".strlen($payload); + reset($this->outgoing_headers); + foreach($this->outgoing_headers as $hdr){ + header($hdr, false); + } + print $payload; + $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; + } + + /** + * takes the value that was created by parsing the request + * and compares to the method's signature, if available. + * + * @param string $operation The operation to be invoked + * @param array $request The array of parameter values + * @return boolean Whether the operation was found + * @access private + */ + function verify_method($operation,$request){ + if(isset($this->wsdl) && is_object($this->wsdl)){ + if($this->wsdl->getOperationData($operation)){ + return true; + } + } elseif(isset($this->operations[$operation])){ + return true; + } + return false; + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Request not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + // parse response, get soap parser obj + $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8); + // parser debug + $this->debug("parser debug: \n".$parser->getDebug()); + // if fault occurred during message parsing + if($err = $parser->getError()){ + $this->result = 'fault: error in msg parsing: '.$err; + $this->fault('Client',"error in msg parsing:\n".$err); + // else successfully parsed request into soapval object + } else { + // get/set methodname + $this->methodURI = $parser->root_struct_namespace; + $this->methodname = $parser->root_struct_name; + $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); + $this->debug('calling parser->get_response()'); + $this->methodparams = $parser->get_response(); + // get SOAP headers + $this->requestHeaders = $parser->getHeaders(); + // add document for doclit support + $this->document = $parser->document; + } + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /** + * add a method to the dispatch map (this has been replaced by the register method) + * + * @param string $methodname + * @param string $in array of input values + * @param string $out array of output values + * @access public + * @deprecated + */ + function add_to_map($methodname,$in,$out){ + $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); + } + + /** + * register a service function with the server + * + * @param string $name the name of the PHP function, class.method or class..method + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param mixed $namespace the element namespace for the method or false + * @param mixed $soapaction the soapaction for the method or false + * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param mixed $use optional (encoded|literal) or false + * @param string $documentation optional Description to include in WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ + global $HTTP_SERVER_VARS; + + if($this->externalWSDLURL){ + die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); + } + if (! $name) { + die('You must specify a name when you register an operation'); + } + if (!is_array($in)) { + die('You must provide an array for operation inputs'); + } + if (!is_array($out)) { + die('You must provide an array for operation outputs'); + } + if(false == $namespace) { + } + if(false == $soapaction) { + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; + } + if(false == $style) { + $style = "rpc"; + } + if(false == $use) { + $use = "encoded"; + } + if ($use == 'encoded' && $encodingStyle = '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + $this->operations[$name] = array( + 'name' => $name, + 'in' => $in, + 'out' => $out, + 'namespace' => $namespace, + 'soapaction' => $soapaction, + 'style' => $style); + if($this->wsdl){ + $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); + } + return true; + } + + /** + * Specify a fault to be returned to the client. + * This also acts as a flag to the server that a fault has occured. + * + * @param string $faultcode + * @param string $faultstring + * @param string $faultactor + * @param string $faultdetail + * @access public + */ + function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ + if ($faultdetail == '' && $this->debug_flag) { + $faultdetail = $this->getDebug(); + } + $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); + $this->fault->soap_defencoding = $this->soap_defencoding; + } + + /** + * Sets up wsdl object. + * Acts as a flag to enable internal WSDL generation + * + * @param string $serviceName, name of the service + * @param mixed $namespace optional 'tns' service namespace or false + * @param mixed $endpoint optional URL of service endpoint or false + * @param string $style optional (rpc|document) WSDL style (also specified by operation) + * @param string $transport optional SOAP transport + * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false + */ + function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) + { + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SERVER_PORT = $_SERVER['SERVER_PORT']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + $HTTPS = $_SERVER['HTTPS']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + $HTTPS = $HTTP_SERVER_VARS['HTTPS']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + if ($SERVER_PORT == 80) { + $SERVER_PORT = ''; + } else { + $SERVER_PORT = ':' . $SERVER_PORT; + } + if(false == $namespace) { + $namespace = "http://$SERVER_NAME/soap/$serviceName"; + } + + if(false == $endpoint) { + if ($HTTPS == '1' || $HTTPS == 'on') { + $SCHEME = 'https'; + } else { + $SCHEME = 'http'; + } + $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; + } + + if(false == $schemaTargetNamespace) { + $schemaTargetNamespace = $namespace; + } + + $this->wsdl = new wsdl; + $this->wsdl->serviceName = $serviceName; + $this->wsdl->endpoint = $endpoint; + $this->wsdl->namespaces['tns'] = $namespace; + $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; + $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; + if ($schemaTargetNamespace != $namespace) { + $this->wsdl->namespaces['types'] = $schemaTargetNamespace; + } + $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); + $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->bindings[$serviceName.'Binding'] = array( + 'name'=>$serviceName.'Binding', + 'style'=>$style, + 'transport'=>$transport, + 'portType'=>$serviceName.'PortType'); + $this->wsdl->ports[$serviceName.'Port'] = array( + 'binding'=>$serviceName.'Binding', + 'location'=>$endpoint, + 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); + } +} + + + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.soap_transport_http.php b/htdocs/includes/nusoap/lib/class.soap_transport_http.php index 71bd0678207c2e3e81b02c0eea226d255f2a18fe..078850080ea99cf80062d438d5fc2009ea5698a7 100644 --- a/htdocs/includes/nusoap/lib/class.soap_transport_http.php +++ b/htdocs/includes/nusoap/lib/class.soap_transport_http.php @@ -1,1038 +1,1038 @@ -<?php - - - - -/** -* transport class for sending/receiving data via HTTP and HTTPS -* NOTE: PHP must be compiled with the CURL extension for HTTPS support -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_transport_http extends nusoap_base { - - var $url = ''; - var $uri = ''; - var $digest_uri = ''; - var $scheme = ''; - var $host = ''; - var $port = ''; - var $path = ''; - var $request_method = 'POST'; - var $protocol_version = '1.0'; - var $encoding = ''; - var $outgoing_headers = array(); - var $incoming_headers = array(); - var $incoming_cookies = array(); - var $outgoing_payload = ''; - var $incoming_payload = ''; - var $useSOAPAction = true; - var $persistentConnection = false; - var $ch = false; // cURL handle - var $username = ''; - var $password = ''; - var $authtype = ''; - var $digestRequest = array(); - var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) - // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' - // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' - // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' - // passphrase: SSL key password/passphrase - // verifypeer: default is 1 - // verifyhost: default is 1 - - /** - * constructor - */ - function soap_transport_http($url){ - parent::nusoap_base(); - $this->setURL($url); - ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); - $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; - $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); - } - - function setURL($url) { - $this->url = $url; - - $u = parse_url($url); - foreach($u as $k => $v){ - $this->debug("$k = $v"); - $this->$k = $v; - } - - // add any GET params to path - if(isset($u['query']) && $u['query'] != ''){ - $this->path .= '?' . $u['query']; - } - - // set default port - if(!isset($u['port'])){ - if($u['scheme'] == 'https'){ - $this->port = 443; - } else { - $this->port = 80; - } - } - - $this->uri = $this->path; - $this->digest_uri = $this->uri; - - // build headers - if (!isset($u['port'])) { - $this->outgoing_headers['Host'] = $this->host; - } else { - $this->outgoing_headers['Host'] = $this->host.':'.$this->port; - } - $this->debug('set Host: ' . $this->outgoing_headers['Host']); - - if (isset($u['user']) && $u['user'] != '') { - $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); - } - } - - function connect($connection_timeout=0,$response_timeout=30){ - // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like - // "regular" socket. - // TODO: disabled for now because OpenSSL must be *compiled* in (not just - // loaded), and until PHP5 stream_get_wrappers is not available. -// if ($this->scheme == 'https') { -// if (version_compare(phpversion(), '4.3.0') >= 0) { -// if (extension_loaded('openssl')) { -// $this->scheme = 'ssl'; -// $this->debug('Using SSL over OpenSSL'); -// } -// } -// } - $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); - if ($this->scheme == 'http' || $this->scheme == 'ssl') { - // use persistent connection - if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ - if (!feof($this->fp)) { - $this->debug('Re-use persistent connection'); - return true; - } - fclose($this->fp); - $this->debug('Closed persistent connection at EOF'); - } - - // munge host if using OpenSSL - if ($this->scheme == 'ssl') { - $host = 'ssl://' . $this->host; - } else { - $host = $this->host; - } - $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); - - // open socket - if($connection_timeout > 0){ - $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); - } else { - $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); - } - - // test pointer - if(!$this->fp) { - $msg = 'Couldn\'t open socket connection to server ' . $this->url; - if ($this->errno) { - $msg .= ', Error ('.$this->errno.'): '.$this->error_str; - } else { - $msg .= ' prior to connect(). This is often a problem looking up the host name.'; - } - $this->debug($msg); - $this->setError($msg); - return false; - } - - // set response timeout - $this->debug('set response timeout to ' . $response_timeout); - socket_set_timeout( $this->fp, $response_timeout); - - $this->debug('socket connected'); - return true; - } else if ($this->scheme == 'https') { - if (!extension_loaded('curl')) { - $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); - return false; - } - $this->debug('connect using https'); - // init CURL - $this->ch = curl_init(); - // set url - $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; - // add path - $hostURL .= $this->path; - curl_setopt($this->ch, CURLOPT_URL, $hostURL); - // follow location headers (re-directs) - curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); - // ask for headers in the response output - curl_setopt($this->ch, CURLOPT_HEADER, 1); - // ask for the response output as the return value - curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); - // encode - // We manage this ourselves through headers and encoding -// if(function_exists('gzuncompress')){ -// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); -// } - // persistent connection - if ($this->persistentConnection) { - // The way we send data, we cannot use persistent connections, since - // there will be some "junk" at the end of our request. - //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); - $this->persistentConnection = false; - $this->outgoing_headers['Connection'] = 'close'; - $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); - } - // set timeout - if ($connection_timeout != 0) { - curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); - } - // TODO: cURL has added a connection timeout separate from the response timeout - //if ($connection_timeout != 0) { - // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); - //} - //if ($response_timeout != 0) { - // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); - //} - - // recent versions of cURL turn on peer/host checking by default, - // while PHP binaries are not compiled with a default location for the - // CA cert bundle, so disable peer/host checking. -//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); - curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); - - // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) - if ($this->authtype == 'certificate') { - if (isset($this->certRequest['cainfofile'])) { - curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); - } - if (isset($this->certRequest['verifypeer'])) { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); - } else { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); - } - if (isset($this->certRequest['verifyhost'])) { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); - } else { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); - } - if (isset($this->certRequest['sslcertfile'])) { - curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); - } - if (isset($this->certRequest['sslkeyfile'])) { - curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); - } - if (isset($this->certRequest['passphrase'])) { - curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); - } - } - $this->debug('cURL connection set up'); - return true; - } else { - $this->setError('Unknown scheme ' . $this->scheme); - $this->debug('Unknown scheme ' . $this->scheme); - return false; - } - } - - /** - * send the SOAP message via HTTP - * - * @param string $data message data - * @param integer $timeout set connection timeout in seconds - * @param integer $response_timeout set response timeout in seconds - * @param array $cookies cookies to send - * @return string data - * @access public - */ - function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { - - $this->debug('entered send() with data of length: '.strlen($data)); - - $this->tryagain = true; - $tries = 0; - while ($this->tryagain) { - $this->tryagain = false; - if ($tries++ < 2) { - // make connnection - if (!$this->connect($timeout, $response_timeout)){ - return false; - } - - // send request - if (!$this->sendRequest($data, $cookies)){ - return false; - } - - // get response - $respdata = $this->getResponse(); - } else { - $this->setError('Too many tries to get an OK response'); - } - } - $this->debug('end of send()'); - return $respdata; - } - - - /** - * send the SOAP message via HTTPS 1.0 using CURL - * - * @param string $msg message data - * @param integer $timeout set connection timeout in seconds - * @param integer $response_timeout set response timeout in seconds - * @param array $cookies cookies to send - * @return string data - * @access public - */ - function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { - return $this->send($data, $timeout, $response_timeout, $cookies); - } - - /** - * if authenticating, set user credentials here - * - * @param string $username - * @param string $password - * @param string $authtype (basic, digest, certificate) - * @param array $digestRequest (keys must be nonce, nc, realm, qop) - * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) - * @access public - */ - function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { - $this->debug("Set credentials for authtype $authtype"); - // cf. RFC 2617 - if ($authtype == 'basic') { - $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); - } elseif ($authtype == 'digest') { - if (isset($digestRequest['nonce'])) { - $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; - - // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) - - // A1 = unq(username-value) ":" unq(realm-value) ":" passwd - $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; - - // H(A1) = MD5(A1) - $HA1 = md5($A1); - - // A2 = Method ":" digest-uri-value - $A2 = 'POST:' . $this->digest_uri; - - // H(A2) - $HA2 = md5($A2); - - // KD(secret, data) = H(concat(secret, ":", data)) - // if qop == auth: - // request-digest = <"> < KD ( H(A1), unq(nonce-value) - // ":" nc-value - // ":" unq(cnonce-value) - // ":" unq(qop-value) - // ":" H(A2) - // ) <"> - // if qop is missing, - // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> - - $unhashedDigest = ''; - $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; - $cnonce = $nonce; - if ($digestRequest['qop'] != '') { - $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; - } else { - $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; - } - - $hashedDigest = md5($unhashedDigest); - - $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; - } - } elseif ($authtype == 'certificate') { - $this->certRequest = $certRequest; - } - $this->username = $username; - $this->password = $password; - $this->authtype = $authtype; - $this->digestRequest = $digestRequest; - - if (isset($this->outgoing_headers['Authorization'])) { - $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); - } else { - $this->debug('Authorization header not set'); - } - } - - /** - * set the soapaction value - * - * @param string $soapaction - * @access public - */ - function setSOAPAction($soapaction) { - $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; - $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); - } - - /** - * use http encoding - * - * @param string $enc encoding style. supported values: gzip, deflate, or both - * @access public - */ - function setEncoding($enc='gzip, deflate') { - if (function_exists('gzdeflate')) { - $this->protocol_version = '1.1'; - $this->outgoing_headers['Accept-Encoding'] = $enc; - $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); - if (!isset($this->outgoing_headers['Connection'])) { - $this->outgoing_headers['Connection'] = 'close'; - $this->persistentConnection = false; - $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); - } - set_magic_quotes_runtime(0); - // deprecated - $this->encoding = $enc; - } - } - - /** - * set proxy info here - * - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @access public - */ - function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { - $this->uri = $this->url; - $this->host = $proxyhost; - $this->port = $proxyport; - if ($proxyusername != '' && $proxypassword != '') { - $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); - $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); - } - } - - /** - * decode a string that is encoded w/ "chunked' transfer encoding - * as defined in RFC2068 19.4.6 - * - * @param string $buffer - * @param string $lb - * @returns string - * @access public - * @deprecated - */ - function decodeChunked($buffer, $lb){ - // length := 0 - $length = 0; - $new = ''; - - // read chunk-size, chunk-extension (if any) and CRLF - // get the position of the linebreak - $chunkend = strpos($buffer, $lb); - if ($chunkend == FALSE) { - $this->debug('no linebreak found in decodeChunked'); - return $new; - } - $temp = substr($buffer,0,$chunkend); - $chunk_size = hexdec( trim($temp) ); - $chunkstart = $chunkend + strlen($lb); - // while (chunk-size > 0) { - while ($chunk_size > 0) { - $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); - $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); - - // Just in case we got a broken connection - if ($chunkend == FALSE) { - $chunk = substr($buffer,$chunkstart); - // append chunk-data to entity-body - $new .= $chunk; - $length += strlen($chunk); - break; - } - - // read chunk-data and CRLF - $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); - // append chunk-data to entity-body - $new .= $chunk; - // length := length + chunk-size - $length += strlen($chunk); - // read chunk-size and CRLF - $chunkstart = $chunkend + strlen($lb); - - $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); - if ($chunkend == FALSE) { - break; //Just in case we got a broken connection - } - $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); - $chunk_size = hexdec( trim($temp) ); - $chunkstart = $chunkend; - } - return $new; - } - - /* - * Writes payload, including HTTP headers, to $this->outgoing_payload. - */ - function buildPayload($data, $cookie_str = '') { - // add content-length header - $this->outgoing_headers['Content-Length'] = strlen($data); - $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); - - // start building outgoing payload: - $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; - $this->debug("HTTP request: $req"); - $this->outgoing_payload = "$req\r\n"; - - // loop thru headers, serializing - foreach($this->outgoing_headers as $k => $v){ - $hdr = $k.': '.$v; - $this->debug("HTTP header: $hdr"); - $this->outgoing_payload .= "$hdr\r\n"; - } - - // add any cookies - if ($cookie_str != '') { - $hdr = 'Cookie: '.$cookie_str; - $this->debug("HTTP header: $hdr"); - $this->outgoing_payload .= "$hdr\r\n"; - } - - // header/body separator - $this->outgoing_payload .= "\r\n"; - - // add data - $this->outgoing_payload .= $data; - } - - function sendRequest($data, $cookies = NULL) { - // build cookie string - $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); - - // build payload - $this->buildPayload($data, $cookie_str); - - if ($this->scheme == 'http' || $this->scheme == 'ssl') { - // send payload - if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { - $this->setError('couldn\'t write message data to socket'); - $this->debug('couldn\'t write message data to socket'); - return false; - } - $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); - return true; - } else if ($this->scheme == 'https') { - // set payload - // TODO: cURL does say this should only be the verb, and in fact it - // turns out that the URI and HTTP version are appended to this, which - // some servers refuse to work with - //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); - foreach($this->outgoing_headers as $k => $v){ - $curl_headers[] = "$k: $v"; - } - if ($cookie_str != '') { - $curl_headers[] = 'Cookie: ' . $cookie_str; - } - curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); - if ($this->request_method == "POST") { - curl_setopt($this->ch, CURLOPT_POST, 1); - curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); - } else { - } - $this->debug('set cURL payload'); - return true; - } - } - - function getResponse(){ - $this->incoming_payload = ''; - - if ($this->scheme == 'http' || $this->scheme == 'ssl') { - // loop until headers have been retrieved - $data = ''; - while (!isset($lb)){ - - // We might EOF during header read. - if(feof($this->fp)) { - $this->incoming_payload = $data; - $this->debug('found no headers before EOF after length ' . strlen($data)); - $this->debug("received before EOF:\n" . $data); - $this->setError('server failed to send headers'); - return false; - } - - $tmp = fgets($this->fp, 256); - $tmplen = strlen($tmp); - $this->debug("read line of $tmplen bytes: " . trim($tmp)); - - if ($tmplen == 0) { - $this->incoming_payload = $data; - $this->debug('socket read of headers timed out after length ' . strlen($data)); - $this->debug("read before timeout: " . $data); - $this->setError('socket read of headers timed out'); - return false; - } - - $data .= $tmp; - $pos = strpos($data,"\r\n\r\n"); - if($pos > 1){ - $lb = "\r\n"; - } else { - $pos = strpos($data,"\n\n"); - if($pos > 1){ - $lb = "\n"; - } - } - // remove 100 header - if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ - unset($lb); - $data = ''; - }// - } - // store header data - $this->incoming_payload .= $data; - $this->debug('found end of headers after length ' . strlen($data)); - // process headers - $header_data = trim(substr($data,0,$pos)); - $header_array = explode($lb,$header_data); - $this->incoming_headers = array(); - $this->incoming_cookies = array(); - foreach($header_array as $header_line){ - $arr = explode(':',$header_line, 2); - if(count($arr) > 1){ - $header_name = strtolower(trim($arr[0])); - $this->incoming_headers[$header_name] = trim($arr[1]); - if ($header_name == 'set-cookie') { - // TODO: allow multiple cookies from parseCookie - $cookie = $this->parseCookie(trim($arr[1])); - if ($cookie) { - $this->incoming_cookies[] = $cookie; - $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); - } else { - $this->debug('did not find cookie in ' . trim($arr[1])); - } - } - } else if (isset($header_name)) { - // append continuation line to previous header - $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; - } - } - - // loop until msg has been received - if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { - $content_length = 2147483647; // ignore any content-length header - $chunked = true; - $this->debug("want to read chunked content"); - } elseif (isset($this->incoming_headers['content-length'])) { - $content_length = $this->incoming_headers['content-length']; - $chunked = false; - $this->debug("want to read content of length $content_length"); - } else { - $content_length = 2147483647; - $chunked = false; - $this->debug("want to read content to EOF"); - } - $data = ''; - do { - if ($chunked) { - $tmp = fgets($this->fp, 256); - $tmplen = strlen($tmp); - $this->debug("read chunk line of $tmplen bytes"); - if ($tmplen == 0) { - $this->incoming_payload = $data; - $this->debug('socket read of chunk length timed out after length ' . strlen($data)); - $this->debug("read before timeout:\n" . $data); - $this->setError('socket read of chunk length timed out'); - return false; - } - $content_length = hexdec(trim($tmp)); - $this->debug("chunk length $content_length"); - } - $strlen = 0; - while (($strlen < $content_length) && (!feof($this->fp))) { - $readlen = min(8192, $content_length - $strlen); - $tmp = fread($this->fp, $readlen); - $tmplen = strlen($tmp); - $this->debug("read buffer of $tmplen bytes"); - if (($tmplen == 0) && (!feof($this->fp))) { - $this->incoming_payload = $data; - $this->debug('socket read of body timed out after length ' . strlen($data)); - $this->debug("read before timeout:\n" . $data); - $this->setError('socket read of body timed out'); - return false; - } - $strlen += $tmplen; - $data .= $tmp; - } - if ($chunked && ($content_length > 0)) { - $tmp = fgets($this->fp, 256); - $tmplen = strlen($tmp); - $this->debug("read chunk terminator of $tmplen bytes"); - if ($tmplen == 0) { - $this->incoming_payload = $data; - $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); - $this->debug("read before timeout:\n" . $data); - $this->setError('socket read of chunk terminator timed out'); - return false; - } - } - } while ($chunked && ($content_length > 0) && (!feof($this->fp))); - if (feof($this->fp)) { - $this->debug('read to EOF'); - } - $this->debug('read body of length ' . strlen($data)); - $this->incoming_payload .= $data; - $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); - - // close filepointer - if( - (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || - (! $this->persistentConnection) || feof($this->fp)){ - fclose($this->fp); - $this->fp = false; - $this->debug('closed socket'); - } - - // connection was closed unexpectedly - if($this->incoming_payload == ''){ - $this->setError('no response from server'); - return false; - } - - // decode transfer-encoding -// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ -// if(!$data = $this->decodeChunked($data, $lb)){ -// $this->setError('Decoding of chunked data failed'); -// return false; -// } - //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>"; - // set decoded payload -// $this->incoming_payload = $header_data.$lb.$lb.$data; -// } - - } else if ($this->scheme == 'https') { - // send and receive - $this->debug('send and receive with cURL'); - $this->incoming_payload = curl_exec($this->ch); - $data = $this->incoming_payload; - - $cErr = curl_error($this->ch); - if ($cErr != '') { - $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>'; - // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE - foreach(curl_getinfo($this->ch) as $k => $v){ - $err .= "$k: $v<br>"; - } - $this->debug($err); - $this->setError($err); - curl_close($this->ch); - return false; - } else { - //echo '<pre>'; - //var_dump(curl_getinfo($this->ch)); - //echo '</pre>'; - } - // close curl - $this->debug('No cURL error, closing cURL'); - curl_close($this->ch); - - // remove 100 header(s) - while (ereg('^HTTP/1.1 100',$data)) { - if ($pos = strpos($data,"\r\n\r\n")) { - $data = ltrim(substr($data,$pos)); - } elseif($pos = strpos($data,"\n\n") ) { - $data = ltrim(substr($data,$pos)); - } - } - - // separate content from HTTP headers - if ($pos = strpos($data,"\r\n\r\n")) { - $lb = "\r\n"; - } elseif( $pos = strpos($data,"\n\n")) { - $lb = "\n"; - } else { - $this->debug('no proper separation of headers and document'); - $this->setError('no proper separation of headers and document'); - return false; - } - $header_data = trim(substr($data,0,$pos)); - $header_array = explode($lb,$header_data); - $data = ltrim(substr($data,$pos)); - $this->debug('found proper separation of headers and document'); - $this->debug('cleaned data, stringlen: '.strlen($data)); - // clean headers - foreach ($header_array as $header_line) { - $arr = explode(':',$header_line,2); - if(count($arr) > 1){ - $header_name = strtolower(trim($arr[0])); - $this->incoming_headers[$header_name] = trim($arr[1]); - if ($header_name == 'set-cookie') { - // TODO: allow multiple cookies from parseCookie - $cookie = $this->parseCookie(trim($arr[1])); - if ($cookie) { - $this->incoming_cookies[] = $cookie; - $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); - } else { - $this->debug('did not find cookie in ' . trim($arr[1])); - } - } - } else if (isset($header_name)) { - // append continuation line to previous header - $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; - } - } - } - - $arr = explode(' ', $header_array[0], 3); - $http_version = $arr[0]; - $http_status = intval($arr[1]); - $http_reason = count($arr) > 2 ? $arr[2] : ''; - - // see if we need to resend the request with http digest authentication - if (isset($this->incoming_headers['location']) && $http_status == 301) { - $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); - $this->setURL($this->incoming_headers['location']); - $this->tryagain = true; - return false; - } - - // see if we need to resend the request with http digest authentication - if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { - $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); - if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { - $this->debug('Server wants digest authentication'); - // remove "Digest " from our elements - $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); - - // parse elements into array - $digestElements = explode(',', $digestString); - foreach ($digestElements as $val) { - $tempElement = explode('=', trim($val), 2); - $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); - } - - // should have (at least) qop, realm, nonce - if (isset($digestRequest['nonce'])) { - $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); - $this->tryagain = true; - return false; - } - } - $this->debug('HTTP authentication failed'); - $this->setError('HTTP authentication failed'); - return false; - } - - if ( - ($http_status >= 300 && $http_status <= 307) || - ($http_status >= 400 && $http_status <= 417) || - ($http_status >= 501 && $http_status <= 505) - ) { - $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); - return false; - } - - // decode content-encoding - if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ - if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ - // if decoding works, use it. else assume data wasn't gzencoded - if(function_exists('gzinflate')){ - //$timer->setMarker('starting decoding of gzip/deflated content'); - // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) - // this means there are no Zlib headers, although there should be - $this->debug('The gzinflate function exists'); - $datalen = strlen($data); - if ($this->incoming_headers['content-encoding'] == 'deflate') { - if ($degzdata = @gzinflate($data)) { - $data = $degzdata; - $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); - if (strlen($data) < $datalen) { - // test for the case that the payload has been compressed twice - $this->debug('The inflated payload is smaller than the gzipped one; try again'); - if ($degzdata = @gzinflate($data)) { - $data = $degzdata; - $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); - } - } - } else { - $this->debug('Error using gzinflate to inflate the payload'); - $this->setError('Error using gzinflate to inflate the payload'); - } - } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { - if ($degzdata = @gzinflate(substr($data, 10))) { // do our best - $data = $degzdata; - $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); - if (strlen($data) < $datalen) { - // test for the case that the payload has been compressed twice - $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); - if ($degzdata = @gzinflate(substr($data, 10))) { - $data = $degzdata; - $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); - } - } - } else { - $this->debug('Error using gzinflate to un-gzip the payload'); - $this->setError('Error using gzinflate to un-gzip the payload'); - } - } - //$timer->setMarker('finished decoding of gzip/deflated content'); - //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>"; - // set decoded payload - $this->incoming_payload = $header_data.$lb.$lb.$data; - } else { - $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); - $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); - } - } else { - $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); - $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); - } - } else { - $this->debug('No Content-Encoding header'); - } - - if(strlen($data) == 0){ - $this->debug('no data after headers!'); - $this->setError('no data present after HTTP headers'); - return false; - } - - return $data; - } - - function setContentType($type, $charset = false) { - $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); - $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); - } - - function usePersistentConnection(){ - if (isset($this->outgoing_headers['Accept-Encoding'])) { - return false; - } - $this->protocol_version = '1.1'; - $this->persistentConnection = true; - $this->outgoing_headers['Connection'] = 'Keep-Alive'; - $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); - return true; - } - - /** - * parse an incoming Cookie into it's parts - * - * @param string $cookie_str content of cookie - * @return array with data of that cookie - * @access private - */ - /* - * TODO: allow a Set-Cookie string to be parsed into multiple cookies - */ - function parseCookie($cookie_str) { - $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; - $data = split(';', $cookie_str); - $value_str = $data[0]; - - $cookie_param = 'domain='; - $start = strpos($cookie_str, $cookie_param); - if ($start > 0) { - $domain = substr($cookie_str, $start + strlen($cookie_param)); - $domain = substr($domain, 0, strpos($domain, ';')); - } else { - $domain = ''; - } - - $cookie_param = 'expires='; - $start = strpos($cookie_str, $cookie_param); - if ($start > 0) { - $expires = substr($cookie_str, $start + strlen($cookie_param)); - $expires = substr($expires, 0, strpos($expires, ';')); - } else { - $expires = ''; - } - - $cookie_param = 'path='; - $start = strpos($cookie_str, $cookie_param); - if ( $start > 0 ) { - $path = substr($cookie_str, $start + strlen($cookie_param)); - $path = substr($path, 0, strpos($path, ';')); - } else { - $path = '/'; - } - - $cookie_param = ';secure;'; - if (strpos($cookie_str, $cookie_param) !== FALSE) { - $secure = true; - } else { - $secure = false; - } - - $sep_pos = strpos($value_str, '='); - - if ($sep_pos) { - $name = substr($value_str, 0, $sep_pos); - $value = substr($value_str, $sep_pos + 1); - $cookie= array( 'name' => $name, - 'value' => $value, - 'domain' => $domain, - 'path' => $path, - 'expires' => $expires, - 'secure' => $secure - ); - return $cookie; - } - return false; - } - - /** - * sort out cookies for the current request - * - * @param array $cookies array with all cookies - * @param boolean $secure is the send-content secure or not? - * @return string for Cookie-HTTP-Header - * @access private - */ - function getCookiesForRequest($cookies, $secure=false) { - $cookie_str = ''; - if ((! is_null($cookies)) && (is_array($cookies))) { - foreach ($cookies as $cookie) { - if (! is_array($cookie)) { - continue; - } - $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); - if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { - if (strtotime($cookie['expires']) <= time()) { - $this->debug('cookie has expired'); - continue; - } - } - if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { - $domain = preg_quote($cookie['domain']); - if (! preg_match("'.*$domain$'i", $this->host)) { - $this->debug('cookie has different domain'); - continue; - } - } - if ((isset($cookie['path'])) && (! empty($cookie['path']))) { - $path = preg_quote($cookie['path']); - if (! preg_match("'^$path.*'i", $this->path)) { - $this->debug('cookie is for a different path'); - continue; - } - } - if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { - $this->debug('cookie is secure, transport is not'); - continue; - } - $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; - $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); - } - } - return $cookie_str; - } -} - - +<?php + + + + +/** +* transport class for sending/receiving data via HTTP and HTTPS +* NOTE: PHP must be compiled with the CURL extension for HTTPS support +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_transport_http extends nusoap_base { + + var $url = ''; + var $uri = ''; + var $digest_uri = ''; + var $scheme = ''; + var $host = ''; + var $port = ''; + var $path = ''; + var $request_method = 'POST'; + var $protocol_version = '1.0'; + var $encoding = ''; + var $outgoing_headers = array(); + var $incoming_headers = array(); + var $incoming_cookies = array(); + var $outgoing_payload = ''; + var $incoming_payload = ''; + var $useSOAPAction = true; + var $persistentConnection = false; + var $ch = false; // cURL handle + var $username = ''; + var $password = ''; + var $authtype = ''; + var $digestRequest = array(); + var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) + // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' + // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' + // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' + // passphrase: SSL key password/passphrase + // verifypeer: default is 1 + // verifyhost: default is 1 + + /** + * constructor + */ + function soap_transport_http($url){ + parent::nusoap_base(); + $this->setURL($url); + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; + $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); + } + + function setURL($url) { + $this->url = $url; + + $u = parse_url($url); + foreach($u as $k => $v){ + $this->debug("$k = $v"); + $this->$k = $v; + } + + // add any GET params to path + if(isset($u['query']) && $u['query'] != ''){ + $this->path .= '?' . $u['query']; + } + + // set default port + if(!isset($u['port'])){ + if($u['scheme'] == 'https'){ + $this->port = 443; + } else { + $this->port = 80; + } + } + + $this->uri = $this->path; + $this->digest_uri = $this->uri; + + // build headers + if (!isset($u['port'])) { + $this->outgoing_headers['Host'] = $this->host; + } else { + $this->outgoing_headers['Host'] = $this->host.':'.$this->port; + } + $this->debug('set Host: ' . $this->outgoing_headers['Host']); + + if (isset($u['user']) && $u['user'] != '') { + $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); + } + } + + function connect($connection_timeout=0,$response_timeout=30){ + // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like + // "regular" socket. + // TODO: disabled for now because OpenSSL must be *compiled* in (not just + // loaded), and until PHP5 stream_get_wrappers is not available. +// if ($this->scheme == 'https') { +// if (version_compare(phpversion(), '4.3.0') >= 0) { +// if (extension_loaded('openssl')) { +// $this->scheme = 'ssl'; +// $this->debug('Using SSL over OpenSSL'); +// } +// } +// } + $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // use persistent connection + if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ + if (!feof($this->fp)) { + $this->debug('Re-use persistent connection'); + return true; + } + fclose($this->fp); + $this->debug('Closed persistent connection at EOF'); + } + + // munge host if using OpenSSL + if ($this->scheme == 'ssl') { + $host = 'ssl://' . $this->host; + } else { + $host = $this->host; + } + $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); + + // open socket + if($connection_timeout > 0){ + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); + } else { + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); + } + + // test pointer + if(!$this->fp) { + $msg = 'Couldn\'t open socket connection to server ' . $this->url; + if ($this->errno) { + $msg .= ', Error ('.$this->errno.'): '.$this->error_str; + } else { + $msg .= ' prior to connect(). This is often a problem looking up the host name.'; + } + $this->debug($msg); + $this->setError($msg); + return false; + } + + // set response timeout + $this->debug('set response timeout to ' . $response_timeout); + socket_set_timeout( $this->fp, $response_timeout); + + $this->debug('socket connected'); + return true; + } else if ($this->scheme == 'https') { + if (!extension_loaded('curl')) { + $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); + return false; + } + $this->debug('connect using https'); + // init CURL + $this->ch = curl_init(); + // set url + $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; + // add path + $hostURL .= $this->path; + curl_setopt($this->ch, CURLOPT_URL, $hostURL); + // follow location headers (re-directs) + curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); + // ask for headers in the response output + curl_setopt($this->ch, CURLOPT_HEADER, 1); + // ask for the response output as the return value + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); + // encode + // We manage this ourselves through headers and encoding +// if(function_exists('gzuncompress')){ +// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); +// } + // persistent connection + if ($this->persistentConnection) { + // The way we send data, we cannot use persistent connections, since + // there will be some "junk" at the end of our request. + //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); + $this->persistentConnection = false; + $this->outgoing_headers['Connection'] = 'close'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + // set timeout + if ($connection_timeout != 0) { + curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); + } + // TODO: cURL has added a connection timeout separate from the response timeout + //if ($connection_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); + //} + //if ($response_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); + //} + + // recent versions of cURL turn on peer/host checking by default, + // while PHP binaries are not compiled with a default location for the + // CA cert bundle, so disable peer/host checking. +//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); + + // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) + if ($this->authtype == 'certificate') { + if (isset($this->certRequest['cainfofile'])) { + curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); + } + if (isset($this->certRequest['verifypeer'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); + } + if (isset($this->certRequest['verifyhost'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); + } + if (isset($this->certRequest['sslcertfile'])) { + curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); + } + if (isset($this->certRequest['sslkeyfile'])) { + curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); + } + if (isset($this->certRequest['passphrase'])) { + curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); + } + } + $this->debug('cURL connection set up'); + return true; + } else { + $this->setError('Unknown scheme ' . $this->scheme); + $this->debug('Unknown scheme ' . $this->scheme); + return false; + } + } + + /** + * send the SOAP message via HTTP + * + * @param string $data message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { + + $this->debug('entered send() with data of length: '.strlen($data)); + + $this->tryagain = true; + $tries = 0; + while ($this->tryagain) { + $this->tryagain = false; + if ($tries++ < 2) { + // make connnection + if (!$this->connect($timeout, $response_timeout)){ + return false; + } + + // send request + if (!$this->sendRequest($data, $cookies)){ + return false; + } + + // get response + $respdata = $this->getResponse(); + } else { + $this->setError('Too many tries to get an OK response'); + } + } + $this->debug('end of send()'); + return $respdata; + } + + + /** + * send the SOAP message via HTTPS 1.0 using CURL + * + * @param string $msg message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { + return $this->send($data, $timeout, $response_timeout, $cookies); + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic, digest, certificate) + * @param array $digestRequest (keys must be nonce, nc, realm, qop) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { + $this->debug("Set credentials for authtype $authtype"); + // cf. RFC 2617 + if ($authtype == 'basic') { + $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); + } elseif ($authtype == 'digest') { + if (isset($digestRequest['nonce'])) { + $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; + + // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) + + // A1 = unq(username-value) ":" unq(realm-value) ":" passwd + $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; + + // H(A1) = MD5(A1) + $HA1 = md5($A1); + + // A2 = Method ":" digest-uri-value + $A2 = 'POST:' . $this->digest_uri; + + // H(A2) + $HA2 = md5($A2); + + // KD(secret, data) = H(concat(secret, ":", data)) + // if qop == auth: + // request-digest = <"> < KD ( H(A1), unq(nonce-value) + // ":" nc-value + // ":" unq(cnonce-value) + // ":" unq(qop-value) + // ":" H(A2) + // ) <"> + // if qop is missing, + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> + + $unhashedDigest = ''; + $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; + $cnonce = $nonce; + if ($digestRequest['qop'] != '') { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; + } else { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; + } + + $hashedDigest = md5($unhashedDigest); + + $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; + } + } elseif ($authtype == 'certificate') { + $this->certRequest = $certRequest; + } + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->digestRequest = $digestRequest; + + if (isset($this->outgoing_headers['Authorization'])) { + $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); + } else { + $this->debug('Authorization header not set'); + } + } + + /** + * set the soapaction value + * + * @param string $soapaction + * @access public + */ + function setSOAPAction($soapaction) { + $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; + $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); + } + + /** + * use http encoding + * + * @param string $enc encoding style. supported values: gzip, deflate, or both + * @access public + */ + function setEncoding($enc='gzip, deflate') { + if (function_exists('gzdeflate')) { + $this->protocol_version = '1.1'; + $this->outgoing_headers['Accept-Encoding'] = $enc; + $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); + if (!isset($this->outgoing_headers['Connection'])) { + $this->outgoing_headers['Connection'] = 'close'; + $this->persistentConnection = false; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + set_magic_quotes_runtime(0); + // deprecated + $this->encoding = $enc; + } + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->uri = $this->url; + $this->host = $proxyhost; + $this->port = $proxyport; + if ($proxyusername != '' && $proxypassword != '') { + $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); + $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); + } + } + + /** + * decode a string that is encoded w/ "chunked' transfer encoding + * as defined in RFC2068 19.4.6 + * + * @param string $buffer + * @param string $lb + * @returns string + * @access public + * @deprecated + */ + function decodeChunked($buffer, $lb){ + // length := 0 + $length = 0; + $new = ''; + + // read chunk-size, chunk-extension (if any) and CRLF + // get the position of the linebreak + $chunkend = strpos($buffer, $lb); + if ($chunkend == FALSE) { + $this->debug('no linebreak found in decodeChunked'); + return $new; + } + $temp = substr($buffer,0,$chunkend); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend + strlen($lb); + // while (chunk-size > 0) { + while ($chunk_size > 0) { + $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); + $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); + + // Just in case we got a broken connection + if ($chunkend == FALSE) { + $chunk = substr($buffer,$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + $length += strlen($chunk); + break; + } + + // read chunk-data and CRLF + $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + // length := length + chunk-size + $length += strlen($chunk); + // read chunk-size and CRLF + $chunkstart = $chunkend + strlen($lb); + + $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); + if ($chunkend == FALSE) { + break; //Just in case we got a broken connection + } + $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend; + } + return $new; + } + + /* + * Writes payload, including HTTP headers, to $this->outgoing_payload. + */ + function buildPayload($data, $cookie_str = '') { + // add content-length header + $this->outgoing_headers['Content-Length'] = strlen($data); + $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); + + // start building outgoing payload: + $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; + $this->debug("HTTP request: $req"); + $this->outgoing_payload = "$req\r\n"; + + // loop thru headers, serializing + foreach($this->outgoing_headers as $k => $v){ + $hdr = $k.': '.$v; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // add any cookies + if ($cookie_str != '') { + $hdr = 'Cookie: '.$cookie_str; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // header/body separator + $this->outgoing_payload .= "\r\n"; + + // add data + $this->outgoing_payload .= $data; + } + + function sendRequest($data, $cookies = NULL) { + // build cookie string + $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); + + // build payload + $this->buildPayload($data, $cookie_str); + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // send payload + if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { + $this->setError('couldn\'t write message data to socket'); + $this->debug('couldn\'t write message data to socket'); + return false; + } + $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); + return true; + } else if ($this->scheme == 'https') { + // set payload + // TODO: cURL does say this should only be the verb, and in fact it + // turns out that the URI and HTTP version are appended to this, which + // some servers refuse to work with + //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); + foreach($this->outgoing_headers as $k => $v){ + $curl_headers[] = "$k: $v"; + } + if ($cookie_str != '') { + $curl_headers[] = 'Cookie: ' . $cookie_str; + } + curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); + if ($this->request_method == "POST") { + curl_setopt($this->ch, CURLOPT_POST, 1); + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); + } else { + } + $this->debug('set cURL payload'); + return true; + } + } + + function getResponse(){ + $this->incoming_payload = ''; + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // loop until headers have been retrieved + $data = ''; + while (!isset($lb)){ + + // We might EOF during header read. + if(feof($this->fp)) { + $this->incoming_payload = $data; + $this->debug('found no headers before EOF after length ' . strlen($data)); + $this->debug("received before EOF:\n" . $data); + $this->setError('server failed to send headers'); + return false; + } + + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read line of $tmplen bytes: " . trim($tmp)); + + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of headers timed out after length ' . strlen($data)); + $this->debug("read before timeout: " . $data); + $this->setError('socket read of headers timed out'); + return false; + } + + $data .= $tmp; + $pos = strpos($data,"\r\n\r\n"); + if($pos > 1){ + $lb = "\r\n"; + } else { + $pos = strpos($data,"\n\n"); + if($pos > 1){ + $lb = "\n"; + } + } + // remove 100 header + if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ + unset($lb); + $data = ''; + }// + } + // store header data + $this->incoming_payload .= $data; + $this->debug('found end of headers after length ' . strlen($data)); + // process headers + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $this->incoming_headers = array(); + $this->incoming_cookies = array(); + foreach($header_array as $header_line){ + $arr = explode(':',$header_line, 2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + + // loop until msg has been received + if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { + $content_length = 2147483647; // ignore any content-length header + $chunked = true; + $this->debug("want to read chunked content"); + } elseif (isset($this->incoming_headers['content-length'])) { + $content_length = $this->incoming_headers['content-length']; + $chunked = false; + $this->debug("want to read content of length $content_length"); + } else { + $content_length = 2147483647; + $chunked = false; + $this->debug("want to read content to EOF"); + } + $data = ''; + do { + if ($chunked) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk line of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk length timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk length timed out'); + return false; + } + $content_length = hexdec(trim($tmp)); + $this->debug("chunk length $content_length"); + } + $strlen = 0; + while (($strlen < $content_length) && (!feof($this->fp))) { + $readlen = min(8192, $content_length - $strlen); + $tmp = fread($this->fp, $readlen); + $tmplen = strlen($tmp); + $this->debug("read buffer of $tmplen bytes"); + if (($tmplen == 0) && (!feof($this->fp))) { + $this->incoming_payload = $data; + $this->debug('socket read of body timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of body timed out'); + return false; + } + $strlen += $tmplen; + $data .= $tmp; + } + if ($chunked && ($content_length > 0)) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk terminator of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk terminator timed out'); + return false; + } + } + } while ($chunked && ($content_length > 0) && (!feof($this->fp))); + if (feof($this->fp)) { + $this->debug('read to EOF'); + } + $this->debug('read body of length ' . strlen($data)); + $this->incoming_payload .= $data; + $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); + + // close filepointer + if( + (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || + (! $this->persistentConnection) || feof($this->fp)){ + fclose($this->fp); + $this->fp = false; + $this->debug('closed socket'); + } + + // connection was closed unexpectedly + if($this->incoming_payload == ''){ + $this->setError('no response from server'); + return false; + } + + // decode transfer-encoding +// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ +// if(!$data = $this->decodeChunked($data, $lb)){ +// $this->setError('Decoding of chunked data failed'); +// return false; +// } + //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>"; + // set decoded payload +// $this->incoming_payload = $header_data.$lb.$lb.$data; +// } + + } else if ($this->scheme == 'https') { + // send and receive + $this->debug('send and receive with cURL'); + $this->incoming_payload = curl_exec($this->ch); + $data = $this->incoming_payload; + + $cErr = curl_error($this->ch); + if ($cErr != '') { + $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>'; + // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE + foreach(curl_getinfo($this->ch) as $k => $v){ + $err .= "$k: $v<br>"; + } + $this->debug($err); + $this->setError($err); + curl_close($this->ch); + return false; + } else { + //echo '<pre>'; + //var_dump(curl_getinfo($this->ch)); + //echo '</pre>'; + } + // close curl + $this->debug('No cURL error, closing cURL'); + curl_close($this->ch); + + // remove 100 header(s) + while (ereg('^HTTP/1.1 100',$data)) { + if ($pos = strpos($data,"\r\n\r\n")) { + $data = ltrim(substr($data,$pos)); + } elseif($pos = strpos($data,"\n\n") ) { + $data = ltrim(substr($data,$pos)); + } + } + + // separate content from HTTP headers + if ($pos = strpos($data,"\r\n\r\n")) { + $lb = "\r\n"; + } elseif( $pos = strpos($data,"\n\n")) { + $lb = "\n"; + } else { + $this->debug('no proper separation of headers and document'); + $this->setError('no proper separation of headers and document'); + return false; + } + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $data = ltrim(substr($data,$pos)); + $this->debug('found proper separation of headers and document'); + $this->debug('cleaned data, stringlen: '.strlen($data)); + // clean headers + foreach ($header_array as $header_line) { + $arr = explode(':',$header_line,2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + } + + $arr = explode(' ', $header_array[0], 3); + $http_version = $arr[0]; + $http_status = intval($arr[1]); + $http_reason = count($arr) > 2 ? $arr[2] : ''; + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['location']) && $http_status == 301) { + $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); + $this->setURL($this->incoming_headers['location']); + $this->tryagain = true; + return false; + } + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { + $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); + if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { + $this->debug('Server wants digest authentication'); + // remove "Digest " from our elements + $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); + + // parse elements into array + $digestElements = explode(',', $digestString); + foreach ($digestElements as $val) { + $tempElement = explode('=', trim($val), 2); + $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); + } + + // should have (at least) qop, realm, nonce + if (isset($digestRequest['nonce'])) { + $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); + $this->tryagain = true; + return false; + } + } + $this->debug('HTTP authentication failed'); + $this->setError('HTTP authentication failed'); + return false; + } + + if ( + ($http_status >= 300 && $http_status <= 307) || + ($http_status >= 400 && $http_status <= 417) || + ($http_status >= 501 && $http_status <= 505) + ) { + $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); + return false; + } + + // decode content-encoding + if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ + if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ + // if decoding works, use it. else assume data wasn't gzencoded + if(function_exists('gzinflate')){ + //$timer->setMarker('starting decoding of gzip/deflated content'); + // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) + // this means there are no Zlib headers, although there should be + $this->debug('The gzinflate function exists'); + $datalen = strlen($data); + if ($this->incoming_headers['content-encoding'] == 'deflate') { + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The inflated payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to inflate the payload'); + $this->setError('Error using gzinflate to inflate the payload'); + } + } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { + if ($degzdata = @gzinflate(substr($data, 10))) { // do our best + $data = $degzdata; + $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate(substr($data, 10))) { + $data = $degzdata; + $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to un-gzip the payload'); + $this->setError('Error using gzinflate to un-gzip the payload'); + } + } + //$timer->setMarker('finished decoding of gzip/deflated content'); + //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>"; + // set decoded payload + $this->incoming_payload = $header_data.$lb.$lb.$data; + } else { + $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + } + } else { + $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + } + } else { + $this->debug('No Content-Encoding header'); + } + + if(strlen($data) == 0){ + $this->debug('no data after headers!'); + $this->setError('no data present after HTTP headers'); + return false; + } + + return $data; + } + + function setContentType($type, $charset = false) { + $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); + $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); + } + + function usePersistentConnection(){ + if (isset($this->outgoing_headers['Accept-Encoding'])) { + return false; + } + $this->protocol_version = '1.1'; + $this->persistentConnection = true; + $this->outgoing_headers['Connection'] = 'Keep-Alive'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + return true; + } + + /** + * parse an incoming Cookie into it's parts + * + * @param string $cookie_str content of cookie + * @return array with data of that cookie + * @access private + */ + /* + * TODO: allow a Set-Cookie string to be parsed into multiple cookies + */ + function parseCookie($cookie_str) { + $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; + $data = split(';', $cookie_str); + $value_str = $data[0]; + + $cookie_param = 'domain='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $domain = substr($cookie_str, $start + strlen($cookie_param)); + $domain = substr($domain, 0, strpos($domain, ';')); + } else { + $domain = ''; + } + + $cookie_param = 'expires='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $expires = substr($cookie_str, $start + strlen($cookie_param)); + $expires = substr($expires, 0, strpos($expires, ';')); + } else { + $expires = ''; + } + + $cookie_param = 'path='; + $start = strpos($cookie_str, $cookie_param); + if ( $start > 0 ) { + $path = substr($cookie_str, $start + strlen($cookie_param)); + $path = substr($path, 0, strpos($path, ';')); + } else { + $path = '/'; + } + + $cookie_param = ';secure;'; + if (strpos($cookie_str, $cookie_param) !== FALSE) { + $secure = true; + } else { + $secure = false; + } + + $sep_pos = strpos($value_str, '='); + + if ($sep_pos) { + $name = substr($value_str, 0, $sep_pos); + $value = substr($value_str, $sep_pos + 1); + $cookie= array( 'name' => $name, + 'value' => $value, + 'domain' => $domain, + 'path' => $path, + 'expires' => $expires, + 'secure' => $secure + ); + return $cookie; + } + return false; + } + + /** + * sort out cookies for the current request + * + * @param array $cookies array with all cookies + * @param boolean $secure is the send-content secure or not? + * @return string for Cookie-HTTP-Header + * @access private + */ + function getCookiesForRequest($cookies, $secure=false) { + $cookie_str = ''; + if ((! is_null($cookies)) && (is_array($cookies))) { + foreach ($cookies as $cookie) { + if (! is_array($cookie)) { + continue; + } + $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) <= time()) { + $this->debug('cookie has expired'); + continue; + } + } + if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { + $domain = preg_quote($cookie['domain']); + if (! preg_match("'.*$domain$'i", $this->host)) { + $this->debug('cookie has different domain'); + continue; + } + } + if ((isset($cookie['path'])) && (! empty($cookie['path']))) { + $path = preg_quote($cookie['path']); + if (! preg_match("'^$path.*'i", $this->path)) { + $this->debug('cookie is for a different path'); + continue; + } + } + if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { + $this->debug('cookie is secure, transport is not'); + continue; + } + $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; + $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); + } + } + return $cookie_str; + } +} + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.soap_val.php b/htdocs/includes/nusoap/lib/class.soap_val.php index dd5bc1797a0afa7c8df1f4084b60179b081713e8..0b43e0b78c6e237629bcad3ce81d707d9b2fed37 100644 --- a/htdocs/includes/nusoap/lib/class.soap_val.php +++ b/htdocs/includes/nusoap/lib/class.soap_val.php @@ -1,107 +1,107 @@ -<?php - - - - -/** -* For creating serializable abstractions of native PHP types. This class -* allows element name/namespace, XSD type, and XML attributes to be -* associated with a value. This is extremely useful when WSDL is not -* used, but is also useful when WSDL is used with polymorphic types, including -* xsd:anyType and user-defined types. -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soapval extends nusoap_base { - /** - * The XML element name - * - * @var string - * @access private - */ - var $name; - /** - * The XML type name (string or false) - * - * @var mixed - * @access private - */ - var $type; - /** - * The PHP value - * - * @var mixed - * @access private - */ - var $value; - /** - * The XML element namespace (string or false) - * - * @var mixed - * @access private - */ - var $element_ns; - /** - * The XML type namespace (string or false) - * - * @var mixed - * @access private - */ - var $type_ns; - /** - * The XML element attributes (array or false) - * - * @var mixed - * @access private - */ - var $attributes; - - /** - * constructor - * - * @param string $name optional name - * @param mixed $type optional type name - * @param mixed $value optional value - * @param mixed $element_ns optional namespace of value - * @param mixed $type_ns optional namespace of type - * @param mixed $attributes associative array of attributes to add to element serialization - * @access public - */ - function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { - parent::nusoap_base(); - $this->name = $name; - $this->type = $type; - $this->value = $value; - $this->element_ns = $element_ns; - $this->type_ns = $type_ns; - $this->attributes = $attributes; - } - - /** - * return serialized value - * - * @param string $use The WSDL use value (encoded|literal) - * @return string XML data - * @access public - */ - function serialize($use='encoded') { - return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); - } - - /** - * decodes a soapval object into a PHP native type - * - * @return mixed - * @access public - */ - function decode(){ - return $this->value; - } -} - - - - +<?php + + + + +/** +* For creating serializable abstractions of native PHP types. This class +* allows element name/namespace, XSD type, and XML attributes to be +* associated with a value. This is extremely useful when WSDL is not +* used, but is also useful when WSDL is used with polymorphic types, including +* xsd:anyType and user-defined types. +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soapval extends nusoap_base { + /** + * The XML element name + * + * @var string + * @access private + */ + var $name; + /** + * The XML type name (string or false) + * + * @var mixed + * @access private + */ + var $type; + /** + * The PHP value + * + * @var mixed + * @access private + */ + var $value; + /** + * The XML element namespace (string or false) + * + * @var mixed + * @access private + */ + var $element_ns; + /** + * The XML type namespace (string or false) + * + * @var mixed + * @access private + */ + var $type_ns; + /** + * The XML element attributes (array or false) + * + * @var mixed + * @access private + */ + var $attributes; + + /** + * constructor + * + * @param string $name optional name + * @param mixed $type optional type name + * @param mixed $value optional value + * @param mixed $element_ns optional namespace of value + * @param mixed $type_ns optional namespace of type + * @param mixed $attributes associative array of attributes to add to element serialization + * @access public + */ + function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { + parent::nusoap_base(); + $this->name = $name; + $this->type = $type; + $this->value = $value; + $this->element_ns = $element_ns; + $this->type_ns = $type_ns; + $this->attributes = $attributes; + } + + /** + * return serialized value + * + * @param string $use The WSDL use value (encoded|literal) + * @return string XML data + * @access public + */ + function serialize($use='encoded') { + return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); + } + + /** + * decodes a soapval object into a PHP native type + * + * @return mixed + * @access public + */ + function decode(){ + return $this->value; + } +} + + + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.soapclient.php b/htdocs/includes/nusoap/lib/class.soapclient.php index 96f6b26ce123fe8e01723c28016449542f33c666..cb3e8f18c5254ef262d95bed8ed2229ad60279e6 100644 --- a/htdocs/includes/nusoap/lib/class.soapclient.php +++ b/htdocs/includes/nusoap/lib/class.soapclient.php @@ -1,859 +1,859 @@ -<?php - - - - -/** -* -* soapclient higher level class for easy usage. -* -* usage: -* -* // instantiate client with server info -* $soapclient = new soapclient( string path [ ,boolean wsdl] ); -* -* // call method, get results -* echo $soapclient->call( string methodname [ ,array parameters] ); -* -* // bye bye client -* unset($soapclient); -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soapclient extends nusoap_base { - - var $username = ''; - var $password = ''; - var $authtype = ''; - var $certRequest = array(); - var $requestHeaders = false; // SOAP headers in request (text) - var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) - var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) - var $endpoint; - var $forceEndpoint = ''; // overrides WSDL endpoint - var $proxyhost = ''; - var $proxyport = ''; - var $proxyusername = ''; - var $proxypassword = ''; - var $xml_encoding = ''; // character set encoding of incoming (response) messages - var $http_encoding = false; - var $timeout = 0; // HTTP connection timeout - var $response_timeout = 30; // HTTP response timeout - var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error - var $persistentConnection = false; - var $defaultRpcParams = false; // This is no longer used - var $request = ''; // HTTP request - var $response = ''; // HTTP response - var $responseData = ''; // SOAP payload of response - var $cookies = array(); // Cookies from response or for request - var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() - var $operations = array(); // WSDL operations, empty for WSDL initialization error - - /* - * fault related variables - */ - /** - * @var fault - * @access public - */ - var $fault; - /** - * @var faultcode - * @access public - */ - var $faultcode; - /** - * @var faultstring - * @access public - */ - var $faultstring; - /** - * @var faultdetail - * @access public - */ - var $faultdetail; - - /** - * constructor - * - * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) - * @param bool $wsdl optional, set to true if using WSDL - * @param int $portName optional portName in WSDL document - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @param integer $timeout set the connection timeout - * @param integer $response_timeout set the response timeout - * @access public - */ - function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ - parent::nusoap_base(); - $this->endpoint = $endpoint; - $this->proxyhost = $proxyhost; - $this->proxyport = $proxyport; - $this->proxyusername = $proxyusername; - $this->proxypassword = $proxypassword; - $this->timeout = $timeout; - $this->response_timeout = $response_timeout; - - // make values - if($wsdl){ - if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { - $this->wsdl = $endpoint; - $this->endpoint = $this->wsdl->wsdl; - $this->wsdlFile = $this->endpoint; - $this->debug('existing wsdl instance created from ' . $this->endpoint); - } else { - $this->wsdlFile = $this->endpoint; - - // instantiate wsdl object and parse wsdl file - $this->debug('instantiating wsdl class with doc: '.$endpoint); - $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); - } - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - // catch errors - if($errstr = $this->wsdl->getError()){ - $this->debug('got wsdl error: '.$errstr); - $this->setError('wsdl error: '.$errstr); - } elseif($this->operations = $this->wsdl->getOperations()){ - $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); - $this->endpointType = 'wsdl'; - } else { - $this->debug( 'getOperations returned false'); - $this->setError('no operations defined in the WSDL document!'); - } - } else { - $this->debug("instantiate SOAP with endpoint at $endpoint"); - $this->endpointType = 'soap'; - } - } - - /** - * calls method, returns PHP native type - * - * @param string $method SOAP server URL or path - * @param mixed $params An array, associative or simple, of the parameters - * for the method call, or a string that is the XML - * for the call. For rpc style, this call will - * wrap the XML in a tag named after the method, as - * well as the SOAP Envelope and Body. For document - * style, this will only wrap with the Envelope and Body. - * IMPORTANT: when using an array with document style, - * in which case there - * is really one parameter, the root of the fragment - * used in the call, which encloses what programmers - * normally think of parameters. A parameter array - * *must* include the wrapper. - * @param string $namespace optional method namespace (WSDL can override) - * @param string $soapAction optional SOAPAction value (WSDL can override) - * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers - * @param boolean $rpcParams optional (no longer used) - * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) - * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) - * @return mixed response from SOAP call - * @access public - */ - function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ - $this->operation = $operation; - $this->fault = false; - $this->setError(''); - $this->request = ''; - $this->response = ''; - $this->responseData = ''; - $this->faultstring = ''; - $this->faultcode = ''; - $this->opData = array(); - - $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); - $this->appendDebug('params=' . $this->varDump($params)); - $this->appendDebug('headers=' . $this->varDump($headers)); - if ($headers) { - $this->requestHeaders = $headers; - } - // serialize parameters - if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ - // use WSDL for operation - $this->opData = $opData; - $this->debug("found operation"); - $this->appendDebug('opData=' . $this->varDump($opData)); - if (isset($opData['soapAction'])) { - $soapAction = $opData['soapAction']; - } - if (! $this->forceEndpoint) { - $this->endpoint = $opData['endpoint']; - } else { - $this->endpoint = $this->forceEndpoint; - } - $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; - $style = $opData['style']; - $use = $opData['input']['use']; - // add ns to ns array - if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ - $nsPrefix = 'ns' . rand(1000, 9999); - $this->wsdl->namespaces[$nsPrefix] = $namespace; - } - $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); - // serialize payload - if (is_string($params)) { - $this->debug("serializing param string for WSDL operation $operation"); - $payload = $params; - } elseif (is_array($params)) { - $this->debug("serializing param array for WSDL operation $operation"); - $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); - } else { - $this->debug('params must be array or string'); - $this->setError('params must be array or string'); - return false; - } - $usedNamespaces = $this->wsdl->usedNamespaces; - if (isset($opData['input']['encodingStyle'])) { - $encodingStyle = $opData['input']['encodingStyle']; - } else { - $encodingStyle = ''; - } - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - if ($errstr = $this->wsdl->getError()) { - $this->debug('got wsdl error: '.$errstr); - $this->setError('wsdl error: '.$errstr); - return false; - } - } elseif($this->endpointType == 'wsdl') { - // operation not in WSDL - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - $this->setError( 'operation '.$operation.' not present.'); - $this->debug("operation '$operation' not present."); - return false; - } else { - // no WSDL - //$this->namespaces['ns1'] = $namespace; - $nsPrefix = 'ns' . rand(1000, 9999); - // serialize - $payload = ''; - if (is_string($params)) { - $this->debug("serializing param string for operation $operation"); - $payload = $params; - } elseif (is_array($params)) { - $this->debug("serializing param array for operation $operation"); - foreach($params as $k => $v){ - $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); - } - } else { - $this->debug('params must be array or string'); - $this->setError('params must be array or string'); - return false; - } - $usedNamespaces = array(); - if ($use == 'encoded') { - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - } else { - $encodingStyle = ''; - } - } - // wrap RPC calls with method element - if ($style == 'rpc') { - if ($use == 'literal') { - $this->debug("wrapping RPC request with literal method element"); - if ($namespace) { - $payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>"; - } else { - $payload = "<$operation>" . $payload . "</$operation>"; - } - } else { - $this->debug("wrapping RPC request with encoded method element"); - if ($namespace) { - $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . - $payload . - "</$nsPrefix:$operation>"; - } else { - $payload = "<$operation>" . - $payload . - "</$operation>"; - } - } - } - // serialize envelope - $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); - $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); - $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); - // send - $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); - if($errstr = $this->getError()){ - $this->debug('Error: '.$errstr); - return false; - } else { - $this->return = $return; - $this->debug('sent message successfully and got a(n) '.gettype($return)); - $this->appendDebug('return=' . $this->varDump($return)); - - // fault? - if(is_array($return) && isset($return['faultcode'])){ - $this->debug('got fault'); - $this->setError($return['faultcode'].': '.$return['faultstring']); - $this->fault = true; - foreach($return as $k => $v){ - $this->$k = $v; - $this->debug("$k = $v<br>"); - } - return $return; - } elseif ($style == 'document') { - // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), - // we are only going to return the first part here...sorry about that - return $return; - } else { - // array of return values - if(is_array($return)){ - // multiple 'out' parameters, which we return wrapped up - // in the array - if(sizeof($return) > 1){ - return $return; - } - // single 'out' parameter (normally the return value) - $return = array_shift($return); - $this->debug('return shifted value: '); - $this->appendDebug($this->varDump($return)); - return $return; - // nothing returned (ie, echoVoid) - } else { - return ""; - } - } - } - } - - /** - * get available data pertaining to an operation - * - * @param string $operation operation name - * @return array array of data pertaining to the operation - * @access public - */ - function getOperationData($operation){ - if(isset($this->operations[$operation])){ - return $this->operations[$operation]; - } - $this->debug("No data for operation: $operation"); - } - - /** - * send the SOAP message - * - * Note: if the operation has multiple return values - * the return value of this method will be an array - * of those values. - * - * @param string $msg a SOAPx4 soapmsg object - * @param string $soapaction SOAPAction value - * @param integer $timeout set connection timeout in seconds - * @param integer $response_timeout set response timeout in seconds - * @return mixed native PHP types. - * @access private - */ - function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { - $this->checkCookies(); - // detect transport - switch(true){ - // http(s) - case ereg('^http',$this->endpoint): - $this->debug('transporting via HTTP'); - if($this->persistentConnection == true && is_object($this->persistentConnection)){ - $http =& $this->persistentConnection; - } else { - $http = new soap_transport_http($this->endpoint); - if ($this->persistentConnection) { - $http->usePersistentConnection(); - } - } - $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); - $http->setSOAPAction($soapaction); - if($this->proxyhost && $this->proxyport){ - $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); - } - if($this->authtype != '') { - $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); - } - if($this->http_encoding != ''){ - $http->setEncoding($this->http_encoding); - } - $this->debug('sending message, length='.strlen($msg)); - if(ereg('^http:',$this->endpoint)){ - //if(strpos($this->endpoint,'http:')){ - $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); - } elseif(ereg('^https',$this->endpoint)){ - //} elseif(strpos($this->endpoint,'https:')){ - //if(phpversion() == '4.3.0-dev'){ - //$response = $http->send($msg,$timeout,$response_timeout); - //$this->request = $http->outgoing_payload; - //$this->response = $http->incoming_payload; - //} else - $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); - } else { - $this->setError('no http/s in endpoint url'); - } - $this->request = $http->outgoing_payload; - $this->response = $http->incoming_payload; - $this->appendDebug($http->getDebug()); - $this->UpdateCookies($http->incoming_cookies); - - // save transport object if using persistent connections - if ($this->persistentConnection) { - $http->clearDebug(); - if (!is_object($this->persistentConnection)) { - $this->persistentConnection = $http; - } - } - - if($err = $http->getError()){ - $this->setError('HTTP Error: '.$err); - return false; - } elseif($this->getError()){ - return false; - } else { - $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); - return $this->parseResponse($http->incoming_headers, $this->responseData); - } - break; - default: - $this->setError('no transport found, or selected transport is not yet supported!'); - return false; - break; - } - } - - /** - * processes SOAP message returned from server - * - * @param array $headers The HTTP headers - * @param string $data unprocessed response data from server - * @return mixed value of the message, decoded into a PHP type - * @access private - */ - function parseResponse($headers, $data) { - $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); - if (!strstr($headers['content-type'], 'text/xml')) { - $this->setError('Response not of type text/xml'); - return false; - } - if (strpos($headers['content-type'], '=')) { - $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); - $this->debug('Got response encoding: ' . $enc); - if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); - $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8); - // add parser debug data to our debug - $this->appendDebug($parser->getDebug()); - // if parse errors - if($errstr = $parser->getError()){ - $this->setError( $errstr); - // destroy the parser object - unset($parser); - return false; - } else { - // get SOAP headers - $this->responseHeaders = $parser->getHeaders(); - // get decoded message - $return = $parser->get_response(); - // add document for doclit support - $this->document = $parser->document; - // destroy the parser object - unset($parser); - // return decode message - return $return; - } - } - - /** - * sets the SOAP endpoint, which can override WSDL - * - * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override - * @access public - */ - function setEndpoint($endpoint) { - $this->forceEndpoint = $endpoint; - } - - /** - * set the SOAP headers - * - * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers - * @access public - */ - function setHeaders($headers){ - $this->requestHeaders = $headers; - } - - /** - * get the SOAP response headers (namespace resolution incomplete) - * - * @return string - * @access public - */ - function getHeaders(){ - return $this->responseHeaders; - } - - /** - * set proxy info here - * - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @access public - */ - function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { - $this->proxyhost = $proxyhost; - $this->proxyport = $proxyport; - $this->proxyusername = $proxyusername; - $this->proxypassword = $proxypassword; - } - - /** - * if authenticating, set user credentials here - * - * @param string $username - * @param string $password - * @param string $authtype (basic|digest|certificate) - * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) - * @access public - */ - function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { - $this->username = $username; - $this->password = $password; - $this->authtype = $authtype; - $this->certRequest = $certRequest; - } - - /** - * use HTTP encoding - * - * @param string $enc - * @access public - */ - function setHTTPEncoding($enc='gzip, deflate'){ - $this->http_encoding = $enc; - } - - /** - * use HTTP persistent connections if possible - * - * @access public - */ - function useHTTPPersistentConnection(){ - $this->persistentConnection = true; - } - - /** - * gets the default RPC parameter setting. - * If true, default is that call params are like RPC even for document style. - * Each call() can override this value. - * - * This is no longer used. - * - * @return boolean - * @access public - * @deprecated - */ - function getDefaultRpcParams() { - return $this->defaultRpcParams; - } - - /** - * sets the default RPC parameter setting. - * If true, default is that call params are like RPC even for document style - * Each call() can override this value. - * - * This is no longer used. - * - * @param boolean $rpcParams - * @access public - * @deprecated - */ - function setDefaultRpcParams($rpcParams) { - $this->defaultRpcParams = $rpcParams; - } - - /** - * dynamically creates an instance of a proxy class, - * allowing user to directly call methods from wsdl - * - * @return object soap_proxy object - * @access public - */ - function getProxy(){ - $r = rand(); - $evalStr = $this->_getProxyClassCode($r); - //$this->debug("proxy class: $evalStr"; - // eval the class - eval($evalStr); - // instantiate proxy object - eval("\$proxy = new soap_proxy_$r('');"); - // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice - $proxy->endpointType = 'wsdl'; - $proxy->wsdlFile = $this->wsdlFile; - $proxy->wsdl = $this->wsdl; - $proxy->operations = $this->operations; - $proxy->defaultRpcParams = $this->defaultRpcParams; - // transfer other state - $proxy->username = $this->username; - $proxy->password = $this->password; - $proxy->authtype = $this->authtype; - $proxy->proxyhost = $this->proxyhost; - $proxy->proxyport = $this->proxyport; - $proxy->proxyusername = $this->proxyusername; - $proxy->proxypassword = $this->proxypassword; - $proxy->timeout = $this->timeout; - $proxy->response_timeout = $this->response_timeout; - $proxy->http_encoding = $this->http_encoding; - $proxy->persistentConnection = $this->persistentConnection; - $proxy->requestHeaders = $this->requestHeaders; - $proxy->soap_defencoding = $this->soap_defencoding; - $proxy->endpoint = $this->endpoint; - $proxy->forceEndpoint = $this->forceEndpoint; - return $proxy; - } - - /** - * dynamically creates proxy class code - * - * @return string PHP/NuSOAP code for the proxy class - * @access private - */ - function _getProxyClassCode($r) { - if ($this->endpointType != 'wsdl') { - $evalStr = 'A proxy can only be created for a WSDL client'; - $this->setError($evalStr); - return $evalStr; - } - $evalStr = ''; - foreach ($this->operations as $operation => $opData) { - if ($operation != '') { - // create param string and param comment string - if (sizeof($opData['input']['parts']) > 0) { - $paramStr = ''; - $paramArrayStr = ''; - $paramCommentStr = ''; - foreach ($opData['input']['parts'] as $name => $type) { - $paramStr .= "\$$name, "; - $paramArrayStr .= "'$name' => \$$name, "; - $paramCommentStr .= "$type \$$name, "; - } - $paramStr = substr($paramStr, 0, strlen($paramStr)-2); - $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); - $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); - } else { - $paramStr = ''; - $paramCommentStr = 'void'; - } - $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; - $evalStr .= "// $paramCommentStr - function " . str_replace('.', '__', $operation) . "($paramStr) { - \$params = array($paramArrayStr); - return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); - } - "; - unset($paramStr); - unset($paramCommentStr); - } - } - $evalStr = 'class soap_proxy_'.$r.' extends soapclient { - '.$evalStr.' -}'; - return $evalStr; - } - - /** - * dynamically creates proxy class code - * - * @return string PHP/NuSOAP code for the proxy class - * @access public - */ - function getProxyClassCode() { - $r = rand(); - return $this->_getProxyClassCode($r); - } - - /** - * gets the HTTP body for the current request. - * - * @param string $soapmsg The SOAP payload - * @return string The HTTP body, which includes the SOAP payload - * @access private - */ - function getHTTPBody($soapmsg) { - return $soapmsg; - } - - /** - * gets the HTTP content type for the current request. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type for the current request. - * @access private - */ - function getHTTPContentType() { - return 'text/xml'; - } - - /** - * gets the HTTP content type charset for the current request. - * returns false for non-text content types. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type charset for the current request. - * @access private - */ - function getHTTPContentTypeCharset() { - return $this->soap_defencoding; - } - - /* - * whether or not parser should decode utf8 element content - * - * @return always returns true - * @access public - */ - function decodeUTF8($bool){ - $this->decode_utf8 = $bool; - return true; - } - - /** - * adds a new Cookie into $this->cookies array - * - * @param string $name Cookie Name - * @param string $value Cookie Value - * @return if cookie-set was successful returns true, else false - * @access public - */ - function setCookie($name, $value) { - if (strlen($name) == 0) { - return false; - } - $this->cookies[] = array('name' => $name, 'value' => $value); - return true; - } - - /** - * gets all Cookies - * - * @return array with all internal cookies - * @access public - */ - function getCookies() { - return $this->cookies; - } - - /** - * checks all Cookies and delete those which are expired - * - * @return always return true - * @access private - */ - function checkCookies() { - if (sizeof($this->cookies) == 0) { - return true; - } - $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); - $curr_cookies = $this->cookies; - $this->cookies = array(); - foreach ($curr_cookies as $cookie) { - if (! is_array($cookie)) { - $this->debug('Remove cookie that is not an array'); - continue; - } - if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { - if (strtotime($cookie['expires']) > time()) { - $this->cookies[] = $cookie; - } else { - $this->debug('Remove expired cookie ' . $cookie['name']); - } - } else { - $this->cookies[] = $cookie; - } - } - $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); - return true; - } - - /** - * updates the current cookies with a new set - * - * @param array $cookies new cookies with which to update current ones - * @return always return true - * @access private - */ - function UpdateCookies($cookies) { - if (sizeof($this->cookies) == 0) { - // no existing cookies: take whatever is new - if (sizeof($cookies) > 0) { - $this->debug('Setting new cookie(s)'); - $this->cookies = $cookies; - } - return true; - } - if (sizeof($cookies) == 0) { - // no new cookies: keep what we've got - return true; - } - // merge - foreach ($cookies as $newCookie) { - if (!is_array($newCookie)) { - continue; - } - if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { - continue; - } - $newName = $newCookie['name']; - - $found = false; - for ($i = 0; $i < count($this->cookies); $i++) { - $cookie = $this->cookies[$i]; - if (!is_array($cookie)) { - continue; - } - if (!isset($cookie['name'])) { - continue; - } - if ($newName != $cookie['name']) { - continue; - } - $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; - $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; - if ($newDomain != $domain) { - continue; - } - $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; - $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; - if ($newPath != $path) { - continue; - } - $this->cookies[$i] = $newCookie; - $found = true; - $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); - break; - } - if (! $found) { - $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); - $this->cookies[] = $newCookie; - } - } - return true; - } -} -?> +<?php + + + + +/** +* +* soapclient higher level class for easy usage. +* +* usage: +* +* // instantiate client with server info +* $soapclient = new soapclient( string path [ ,boolean wsdl] ); +* +* // call method, get results +* echo $soapclient->call( string methodname [ ,array parameters] ); +* +* // bye bye client +* unset($soapclient); +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soapclient extends nusoap_base { + + var $username = ''; + var $password = ''; + var $authtype = ''; + var $certRequest = array(); + var $requestHeaders = false; // SOAP headers in request (text) + var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) + var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) + var $endpoint; + var $forceEndpoint = ''; // overrides WSDL endpoint + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $xml_encoding = ''; // character set encoding of incoming (response) messages + var $http_encoding = false; + var $timeout = 0; // HTTP connection timeout + var $response_timeout = 30; // HTTP response timeout + var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error + var $persistentConnection = false; + var $defaultRpcParams = false; // This is no longer used + var $request = ''; // HTTP request + var $response = ''; // HTTP response + var $responseData = ''; // SOAP payload of response + var $cookies = array(); // Cookies from response or for request + var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() + var $operations = array(); // WSDL operations, empty for WSDL initialization error + + /* + * fault related variables + */ + /** + * @var fault + * @access public + */ + var $fault; + /** + * @var faultcode + * @access public + */ + var $faultcode; + /** + * @var faultstring + * @access public + */ + var $faultstring; + /** + * @var faultdetail + * @access public + */ + var $faultdetail; + + /** + * constructor + * + * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) + * @param bool $wsdl optional, set to true if using WSDL + * @param int $portName optional portName in WSDL document + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ + parent::nusoap_base(); + $this->endpoint = $endpoint; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // make values + if($wsdl){ + if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { + $this->wsdl = $endpoint; + $this->endpoint = $this->wsdl->wsdl; + $this->wsdlFile = $this->endpoint; + $this->debug('existing wsdl instance created from ' . $this->endpoint); + } else { + $this->wsdlFile = $this->endpoint; + + // instantiate wsdl object and parse wsdl file + $this->debug('instantiating wsdl class with doc: '.$endpoint); + $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + // catch errors + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + } elseif($this->operations = $this->wsdl->getOperations()){ + $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); + $this->endpointType = 'wsdl'; + } else { + $this->debug( 'getOperations returned false'); + $this->setError('no operations defined in the WSDL document!'); + } + } else { + $this->debug("instantiate SOAP with endpoint at $endpoint"); + $this->endpointType = 'soap'; + } + } + + /** + * calls method, returns PHP native type + * + * @param string $method SOAP server URL or path + * @param mixed $params An array, associative or simple, of the parameters + * for the method call, or a string that is the XML + * for the call. For rpc style, this call will + * wrap the XML in a tag named after the method, as + * well as the SOAP Envelope and Body. For document + * style, this will only wrap with the Envelope and Body. + * IMPORTANT: when using an array with document style, + * in which case there + * is really one parameter, the root of the fragment + * used in the call, which encloses what programmers + * normally think of parameters. A parameter array + * *must* include the wrapper. + * @param string $namespace optional method namespace (WSDL can override) + * @param string $soapAction optional SOAPAction value (WSDL can override) + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param boolean $rpcParams optional (no longer used) + * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) + * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) + * @return mixed response from SOAP call + * @access public + */ + function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ + $this->operation = $operation; + $this->fault = false; + $this->setError(''); + $this->request = ''; + $this->response = ''; + $this->responseData = ''; + $this->faultstring = ''; + $this->faultcode = ''; + $this->opData = array(); + + $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); + $this->appendDebug('params=' . $this->varDump($params)); + $this->appendDebug('headers=' . $this->varDump($headers)); + if ($headers) { + $this->requestHeaders = $headers; + } + // serialize parameters + if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ + // use WSDL for operation + $this->opData = $opData; + $this->debug("found operation"); + $this->appendDebug('opData=' . $this->varDump($opData)); + if (isset($opData['soapAction'])) { + $soapAction = $opData['soapAction']; + } + if (! $this->forceEndpoint) { + $this->endpoint = $opData['endpoint']; + } else { + $this->endpoint = $this->forceEndpoint; + } + $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; + $style = $opData['style']; + $use = $opData['input']['use']; + // add ns to ns array + if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ + $nsPrefix = 'ns' . rand(1000, 9999); + $this->wsdl->namespaces[$nsPrefix] = $namespace; + } + $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); + // serialize payload + if (is_string($params)) { + $this->debug("serializing param string for WSDL operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for WSDL operation $operation"); + $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = $this->wsdl->usedNamespaces; + if (isset($opData['input']['encodingStyle'])) { + $encodingStyle = $opData['input']['encodingStyle']; + } else { + $encodingStyle = ''; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if ($errstr = $this->wsdl->getError()) { + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + return false; + } + } elseif($this->endpointType == 'wsdl') { + // operation not in WSDL + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + $this->setError( 'operation '.$operation.' not present.'); + $this->debug("operation '$operation' not present."); + return false; + } else { + // no WSDL + //$this->namespaces['ns1'] = $namespace; + $nsPrefix = 'ns' . rand(1000, 9999); + // serialize + $payload = ''; + if (is_string($params)) { + $this->debug("serializing param string for operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for operation $operation"); + foreach($params as $k => $v){ + $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = array(); + if ($use == 'encoded') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } else { + $encodingStyle = ''; + } + } + // wrap RPC calls with method element + if ($style == 'rpc') { + if ($use == 'literal') { + $this->debug("wrapping RPC request with literal method element"); + if ($namespace) { + $payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>"; + } else { + $payload = "<$operation>" . $payload . "</$operation>"; + } + } else { + $this->debug("wrapping RPC request with encoded method element"); + if ($namespace) { + $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . + $payload . + "</$nsPrefix:$operation>"; + } else { + $payload = "<$operation>" . + $payload . + "</$operation>"; + } + } + } + // serialize envelope + $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); + $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); + $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); + // send + $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); + if($errstr = $this->getError()){ + $this->debug('Error: '.$errstr); + return false; + } else { + $this->return = $return; + $this->debug('sent message successfully and got a(n) '.gettype($return)); + $this->appendDebug('return=' . $this->varDump($return)); + + // fault? + if(is_array($return) && isset($return['faultcode'])){ + $this->debug('got fault'); + $this->setError($return['faultcode'].': '.$return['faultstring']); + $this->fault = true; + foreach($return as $k => $v){ + $this->$k = $v; + $this->debug("$k = $v<br>"); + } + return $return; + } elseif ($style == 'document') { + // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), + // we are only going to return the first part here...sorry about that + return $return; + } else { + // array of return values + if(is_array($return)){ + // multiple 'out' parameters, which we return wrapped up + // in the array + if(sizeof($return) > 1){ + return $return; + } + // single 'out' parameter (normally the return value) + $return = array_shift($return); + $this->debug('return shifted value: '); + $this->appendDebug($this->varDump($return)); + return $return; + // nothing returned (ie, echoVoid) + } else { + return ""; + } + } + } + } + + /** + * get available data pertaining to an operation + * + * @param string $operation operation name + * @return array array of data pertaining to the operation + * @access public + */ + function getOperationData($operation){ + if(isset($this->operations[$operation])){ + return $this->operations[$operation]; + } + $this->debug("No data for operation: $operation"); + } + + /** + * send the SOAP message + * + * Note: if the operation has multiple return values + * the return value of this method will be an array + * of those values. + * + * @param string $msg a SOAPx4 soapmsg object + * @param string $soapaction SOAPAction value + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @return mixed native PHP types. + * @access private + */ + function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { + $this->checkCookies(); + // detect transport + switch(true){ + // http(s) + case ereg('^http',$this->endpoint): + $this->debug('transporting via HTTP'); + if($this->persistentConnection == true && is_object($this->persistentConnection)){ + $http =& $this->persistentConnection; + } else { + $http = new soap_transport_http($this->endpoint); + if ($this->persistentConnection) { + $http->usePersistentConnection(); + } + } + $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); + $http->setSOAPAction($soapaction); + if($this->proxyhost && $this->proxyport){ + $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + if($this->authtype != '') { + $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); + } + if($this->http_encoding != ''){ + $http->setEncoding($this->http_encoding); + } + $this->debug('sending message, length='.strlen($msg)); + if(ereg('^http:',$this->endpoint)){ + //if(strpos($this->endpoint,'http:')){ + $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); + } elseif(ereg('^https',$this->endpoint)){ + //} elseif(strpos($this->endpoint,'https:')){ + //if(phpversion() == '4.3.0-dev'){ + //$response = $http->send($msg,$timeout,$response_timeout); + //$this->request = $http->outgoing_payload; + //$this->response = $http->incoming_payload; + //} else + $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); + } else { + $this->setError('no http/s in endpoint url'); + } + $this->request = $http->outgoing_payload; + $this->response = $http->incoming_payload; + $this->appendDebug($http->getDebug()); + $this->UpdateCookies($http->incoming_cookies); + + // save transport object if using persistent connections + if ($this->persistentConnection) { + $http->clearDebug(); + if (!is_object($this->persistentConnection)) { + $this->persistentConnection = $http; + } + } + + if($err = $http->getError()){ + $this->setError('HTTP Error: '.$err); + return false; + } elseif($this->getError()){ + return false; + } else { + $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); + return $this->parseResponse($http->incoming_headers, $this->responseData); + } + break; + default: + $this->setError('no transport found, or selected transport is not yet supported!'); + return false; + break; + } + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Response not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8); + // add parser debug data to our debug + $this->appendDebug($parser->getDebug()); + // if parse errors + if($errstr = $parser->getError()){ + $this->setError( $errstr); + // destroy the parser object + unset($parser); + return false; + } else { + // get SOAP headers + $this->responseHeaders = $parser->getHeaders(); + // get decoded message + $return = $parser->get_response(); + // add document for doclit support + $this->document = $parser->document; + // destroy the parser object + unset($parser); + // return decode message + return $return; + } + } + + /** + * sets the SOAP endpoint, which can override WSDL + * + * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override + * @access public + */ + function setEndpoint($endpoint) { + $this->forceEndpoint = $endpoint; + } + + /** + * set the SOAP headers + * + * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers + * @access public + */ + function setHeaders($headers){ + $this->requestHeaders = $headers; + } + + /** + * get the SOAP response headers (namespace resolution incomplete) + * + * @return string + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic|digest|certificate) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->certRequest = $certRequest; + } + + /** + * use HTTP encoding + * + * @param string $enc + * @access public + */ + function setHTTPEncoding($enc='gzip, deflate'){ + $this->http_encoding = $enc; + } + + /** + * use HTTP persistent connections if possible + * + * @access public + */ + function useHTTPPersistentConnection(){ + $this->persistentConnection = true; + } + + /** + * gets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style. + * Each call() can override this value. + * + * This is no longer used. + * + * @return boolean + * @access public + * @deprecated + */ + function getDefaultRpcParams() { + return $this->defaultRpcParams; + } + + /** + * sets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style + * Each call() can override this value. + * + * This is no longer used. + * + * @param boolean $rpcParams + * @access public + * @deprecated + */ + function setDefaultRpcParams($rpcParams) { + $this->defaultRpcParams = $rpcParams; + } + + /** + * dynamically creates an instance of a proxy class, + * allowing user to directly call methods from wsdl + * + * @return object soap_proxy object + * @access public + */ + function getProxy(){ + $r = rand(); + $evalStr = $this->_getProxyClassCode($r); + //$this->debug("proxy class: $evalStr"; + // eval the class + eval($evalStr); + // instantiate proxy object + eval("\$proxy = new soap_proxy_$r('');"); + // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice + $proxy->endpointType = 'wsdl'; + $proxy->wsdlFile = $this->wsdlFile; + $proxy->wsdl = $this->wsdl; + $proxy->operations = $this->operations; + $proxy->defaultRpcParams = $this->defaultRpcParams; + // transfer other state + $proxy->username = $this->username; + $proxy->password = $this->password; + $proxy->authtype = $this->authtype; + $proxy->proxyhost = $this->proxyhost; + $proxy->proxyport = $this->proxyport; + $proxy->proxyusername = $this->proxyusername; + $proxy->proxypassword = $this->proxypassword; + $proxy->timeout = $this->timeout; + $proxy->response_timeout = $this->response_timeout; + $proxy->http_encoding = $this->http_encoding; + $proxy->persistentConnection = $this->persistentConnection; + $proxy->requestHeaders = $this->requestHeaders; + $proxy->soap_defencoding = $this->soap_defencoding; + $proxy->endpoint = $this->endpoint; + $proxy->forceEndpoint = $this->forceEndpoint; + return $proxy; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access private + */ + function _getProxyClassCode($r) { + if ($this->endpointType != 'wsdl') { + $evalStr = 'A proxy can only be created for a WSDL client'; + $this->setError($evalStr); + return $evalStr; + } + $evalStr = ''; + foreach ($this->operations as $operation => $opData) { + if ($operation != '') { + // create param string and param comment string + if (sizeof($opData['input']['parts']) > 0) { + $paramStr = ''; + $paramArrayStr = ''; + $paramCommentStr = ''; + foreach ($opData['input']['parts'] as $name => $type) { + $paramStr .= "\$$name, "; + $paramArrayStr .= "'$name' => \$$name, "; + $paramCommentStr .= "$type \$$name, "; + } + $paramStr = substr($paramStr, 0, strlen($paramStr)-2); + $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); + $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); + } else { + $paramStr = ''; + $paramCommentStr = 'void'; + } + $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; + $evalStr .= "// $paramCommentStr + function " . str_replace('.', '__', $operation) . "($paramStr) { + \$params = array($paramArrayStr); + return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); + } + "; + unset($paramStr); + unset($paramCommentStr); + } + } + $evalStr = 'class soap_proxy_'.$r.' extends soapclient { + '.$evalStr.' +}'; + return $evalStr; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access public + */ + function getProxyClassCode() { + $r = rand(); + return $this->_getProxyClassCode($r); + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /* + * whether or not parser should decode utf8 element content + * + * @return always returns true + * @access public + */ + function decodeUTF8($bool){ + $this->decode_utf8 = $bool; + return true; + } + + /** + * adds a new Cookie into $this->cookies array + * + * @param string $name Cookie Name + * @param string $value Cookie Value + * @return if cookie-set was successful returns true, else false + * @access public + */ + function setCookie($name, $value) { + if (strlen($name) == 0) { + return false; + } + $this->cookies[] = array('name' => $name, 'value' => $value); + return true; + } + + /** + * gets all Cookies + * + * @return array with all internal cookies + * @access public + */ + function getCookies() { + return $this->cookies; + } + + /** + * checks all Cookies and delete those which are expired + * + * @return always return true + * @access private + */ + function checkCookies() { + if (sizeof($this->cookies) == 0) { + return true; + } + $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); + $curr_cookies = $this->cookies; + $this->cookies = array(); + foreach ($curr_cookies as $cookie) { + if (! is_array($cookie)) { + $this->debug('Remove cookie that is not an array'); + continue; + } + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) > time()) { + $this->cookies[] = $cookie; + } else { + $this->debug('Remove expired cookie ' . $cookie['name']); + } + } else { + $this->cookies[] = $cookie; + } + } + $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); + return true; + } + + /** + * updates the current cookies with a new set + * + * @param array $cookies new cookies with which to update current ones + * @return always return true + * @access private + */ + function UpdateCookies($cookies) { + if (sizeof($this->cookies) == 0) { + // no existing cookies: take whatever is new + if (sizeof($cookies) > 0) { + $this->debug('Setting new cookie(s)'); + $this->cookies = $cookies; + } + return true; + } + if (sizeof($cookies) == 0) { + // no new cookies: keep what we've got + return true; + } + // merge + foreach ($cookies as $newCookie) { + if (!is_array($newCookie)) { + continue; + } + if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { + continue; + } + $newName = $newCookie['name']; + + $found = false; + for ($i = 0; $i < count($this->cookies); $i++) { + $cookie = $this->cookies[$i]; + if (!is_array($cookie)) { + continue; + } + if (!isset($cookie['name'])) { + continue; + } + if ($newName != $cookie['name']) { + continue; + } + $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; + $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; + if ($newDomain != $domain) { + continue; + } + $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; + $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; + if ($newPath != $path) { + continue; + } + $this->cookies[$i] = $newCookie; + $found = true; + $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); + break; + } + if (! $found) { + $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); + $this->cookies[] = $newCookie; + } + } + return true; + } +} +?> diff --git a/htdocs/includes/nusoap/lib/class.wsdl.php b/htdocs/includes/nusoap/lib/class.wsdl.php index afcd7a3eb6a692e253cd697f2af5ca77f35ba8c6..4abce0c32d744c5732f50cc6ba9a402112074abf 100644 --- a/htdocs/includes/nusoap/lib/class.wsdl.php +++ b/htdocs/includes/nusoap/lib/class.wsdl.php @@ -1,1727 +1,1727 @@ -<?php - - - - -/** -* parses a WSDL file, allows access to it's data, other utility methods -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class wsdl extends nusoap_base { - // URL or filename of the root of this WSDL - var $wsdl; - // define internal arrays of bindings, ports, operations, messages, etc. - var $schemas = array(); - var $currentSchema; - var $message = array(); - var $complexTypes = array(); - var $messages = array(); - var $currentMessage; - var $currentOperation; - var $portTypes = array(); - var $currentPortType; - var $bindings = array(); - var $currentBinding; - var $ports = array(); - var $currentPort; - var $opData = array(); - var $status = ''; - var $documentation = false; - var $endpoint = ''; - // array of wsdl docs to import - var $import = array(); - // parser vars - var $parser; - var $position = 0; - var $depth = 0; - var $depth_array = array(); - // for getting wsdl - var $proxyhost = ''; - var $proxyport = ''; - var $proxyusername = ''; - var $proxypassword = ''; - var $timeout = 0; - var $response_timeout = 30; - - /** - * constructor - * - * @param string $wsdl WSDL document URL - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @param integer $timeout set the connection timeout - * @param integer $response_timeout set the response timeout - * @access public - */ - function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ - parent::nusoap_base(); - $this->wsdl = $wsdl; - $this->proxyhost = $proxyhost; - $this->proxyport = $proxyport; - $this->proxyusername = $proxyusername; - $this->proxypassword = $proxypassword; - $this->timeout = $timeout; - $this->response_timeout = $response_timeout; - - // parse wsdl file - if ($wsdl != "") { - $this->debug('initial wsdl URL: ' . $wsdl); - $this->parseWSDL($wsdl); - } - // imports - // TODO: handle imports more properly, grabbing them in-line and nesting them - $imported_urls = array(); - $imported = 1; - while ($imported > 0) { - $imported = 0; - // Schema imports - foreach ($this->schemas as $ns => $list) { - foreach ($list as $xs) { - $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! - foreach ($xs->imports as $ns2 => $list2) { - for ($ii = 0; $ii < count($list2); $ii++) { - if (! $list2[$ii]['loaded']) { - $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; - $url = $list2[$ii]['location']; - if ($url != '') { - $urlparts = parse_url($url); - if (!isset($urlparts['host'])) { - $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . - substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; - } - if (! in_array($url, $imported_urls)) { - $this->parseWSDL($url); - $imported++; - $imported_urls[] = $url; - } - } else { - $this->debug("Unexpected scenario: empty URL for unloaded import"); - } - } - } - } - } - } - // WSDL imports - $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! - foreach ($this->import as $ns => $list) { - for ($ii = 0; $ii < count($list); $ii++) { - if (! $list[$ii]['loaded']) { - $this->import[$ns][$ii]['loaded'] = true; - $url = $list[$ii]['location']; - if ($url != '') { - $urlparts = parse_url($url); - if (!isset($urlparts['host'])) { - $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . - substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; - } - if (! in_array($url, $imported_urls)) { - $this->parseWSDL($url); - $imported++; - $imported_urls[] = $url; - } - } else { - $this->debug("Unexpected scenario: empty URL for unloaded import"); - } - } - } - } - } - // add new data to operation data - foreach($this->bindings as $binding => $bindingData) { - if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { - foreach($bindingData['operations'] as $operation => $data) { - $this->debug('post-parse data gathering for ' . $operation); - $this->bindings[$binding]['operations'][$operation]['input'] = - isset($this->bindings[$binding]['operations'][$operation]['input']) ? - array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : - $this->portTypes[ $bindingData['portType'] ][$operation]['input']; - $this->bindings[$binding]['operations'][$operation]['output'] = - isset($this->bindings[$binding]['operations'][$operation]['output']) ? - array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : - $this->portTypes[ $bindingData['portType'] ][$operation]['output']; - if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ - $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; - } - if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ - $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; - } - if (isset($bindingData['style'])) { - $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; - } - $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; - $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; - $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; - } - } - } - } - - /** - * parses the wsdl document - * - * @param string $wsdl path or URL - * @access private - */ - function parseWSDL($wsdl = '') - { - if ($wsdl == '') { - $this->debug('no wsdl passed to parseWSDL()!!'); - $this->setError('no wsdl passed to parseWSDL()!!'); - return false; - } - - // parse $wsdl for url format - $wsdl_props = parse_url($wsdl); - - if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { - $this->debug('getting WSDL http(s) URL ' . $wsdl); - // get wsdl - $tr = new soap_transport_http($wsdl); - $tr->request_method = 'GET'; - $tr->useSOAPAction = false; - if($this->proxyhost && $this->proxyport){ - $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); - } - $tr->setEncoding('gzip, deflate'); - $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); - //$this->debug("WSDL request\n" . $tr->outgoing_payload); - //$this->debug("WSDL response\n" . $tr->incoming_payload); - $this->appendDebug($tr->getDebug()); - // catch errors - if($err = $tr->getError() ){ - $errstr = 'HTTP ERROR: '.$err; - $this->debug($errstr); - $this->setError($errstr); - unset($tr); - return false; - } - unset($tr); - $this->debug("got WSDL URL"); - } else { - // $wsdl is not http(s), so treat it as a file URL or plain file path - if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { - $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; - } else { - $path = $wsdl; - } - $this->debug('getting WSDL file ' . $path); - if ($fp = @fopen($path, 'r')) { - $wsdl_string = ''; - while ($data = fread($fp, 32768)) { - $wsdl_string .= $data; - } - fclose($fp); - } else { - $errstr = "Bad path to WSDL file $path"; - $this->debug($errstr); - $this->setError($errstr); - return false; - } - } - $this->debug('Parse WSDL'); - // end new code added - // Create an XML parser. - $this->parser = xml_parser_create(); - // Set the options for parsing the XML data. - // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); - xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); - // Set the object for the parser. - xml_set_object($this->parser, $this); - // Set the element handlers for the parser. - xml_set_element_handler($this->parser, 'start_element', 'end_element'); - xml_set_character_data_handler($this->parser, 'character_data'); - // Parse the XML file. - if (!xml_parse($this->parser, $wsdl_string, true)) { - // Display an error message. - $errstr = sprintf( - 'XML error parsing WSDL from %s on line %d: %s', - $wsdl, - xml_get_current_line_number($this->parser), - xml_error_string(xml_get_error_code($this->parser)) - ); - $this->debug($errstr); - $this->debug("XML payload:\n" . $wsdl_string); - $this->setError($errstr); - return false; - } - // free the parser - xml_parser_free($this->parser); - $this->debug('Parsing WSDL done'); - // catch wsdl parse errors - if($this->getError()){ - return false; - } - return true; - } - - /** - * start-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @param string $attrs associative array of attributes - * @access private - */ - function start_element($parser, $name, $attrs) - { - if ($this->status == 'schema') { - $this->currentSchema->schemaStartElement($parser, $name, $attrs); - $this->appendDebug($this->currentSchema->getDebug()); - $this->currentSchema->clearDebug(); - } elseif (ereg('schema$', $name)) { - $this->debug('Parsing WSDL schema'); - // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); - $this->status = 'schema'; - $this->currentSchema = new xmlschema('', '', $this->namespaces); - $this->currentSchema->schemaStartElement($parser, $name, $attrs); - $this->appendDebug($this->currentSchema->getDebug()); - $this->currentSchema->clearDebug(); - } else { - // position in the total number of elements, starting from 0 - $pos = $this->position++; - $depth = $this->depth++; - // set self as current value for this depth - $this->depth_array[$depth] = $pos; - $this->message[$pos] = array('cdata' => ''); - // process attributes - if (count($attrs) > 0) { - // register namespace declarations - foreach($attrs as $k => $v) { - if (ereg("^xmlns", $k)) { - if ($ns_prefix = substr(strrchr($k, ':'), 1)) { - $this->namespaces[$ns_prefix] = $v; - } else { - $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; - } - if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { - $this->XMLSchemaVersion = $v; - $this->namespaces['xsi'] = $v . '-instance'; - } - } - } - // expand each attribute prefix to its namespace - foreach($attrs as $k => $v) { - $k = strpos($k, ':') ? $this->expandQname($k) : $k; - if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { - $v = strpos($v, ':') ? $this->expandQname($v) : $v; - } - $eAttrs[$k] = $v; - } - $attrs = $eAttrs; - } else { - $attrs = array(); - } - // get element prefix, namespace and name - if (ereg(':', $name)) { - // get ns prefix - $prefix = substr($name, 0, strpos($name, ':')); - // get ns - $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; - // get unqualified name - $name = substr(strstr($name, ':'), 1); - } - // process attributes, expanding any prefixes to namespaces - // find status, register data - switch ($this->status) { - case 'message': - if ($name == 'part') { - if (isset($attrs['type'])) { - $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); - $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; - } - if (isset($attrs['element'])) { - $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); - $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; - } - } - break; - case 'portType': - switch ($name) { - case 'operation': - $this->currentPortOperation = $attrs['name']; - $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); - if (isset($attrs['parameterOrder'])) { - $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; - } - break; - case 'documentation': - $this->documentation = true; - break; - // merge input/output data - default: - $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; - $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; - break; - } - break; - case 'binding': - switch ($name) { - case 'binding': - // get ns prefix - if (isset($attrs['style'])) { - $this->bindings[$this->currentBinding]['prefix'] = $prefix; - } - $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); - break; - case 'header': - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; - break; - case 'operation': - if (isset($attrs['soapAction'])) { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; - } - if (isset($attrs['style'])) { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; - } - if (isset($attrs['name'])) { - $this->currentOperation = $attrs['name']; - $this->debug("current binding operation: $this->currentOperation"); - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; - } - break; - case 'input': - $this->opStatus = 'input'; - break; - case 'output': - $this->opStatus = 'output'; - break; - case 'body': - if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); - } else { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; - } - break; - } - break; - case 'service': - switch ($name) { - case 'port': - $this->currentPort = $attrs['name']; - $this->debug('current port: ' . $this->currentPort); - $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); - - break; - case 'address': - $this->ports[$this->currentPort]['location'] = $attrs['location']; - $this->ports[$this->currentPort]['bindingType'] = $namespace; - $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; - $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; - break; - } - break; - } - // set status - switch ($name) { - case 'import': - if (isset($attrs['location'])) { - $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); - $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); - } else { - $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); - if (! $this->getPrefixFromNamespace($attrs['namespace'])) { - $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; - } - $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); - } - break; - //wait for schema - //case 'types': - // $this->status = 'schema'; - // break; - case 'message': - $this->status = 'message'; - $this->messages[$attrs['name']] = array(); - $this->currentMessage = $attrs['name']; - break; - case 'portType': - $this->status = 'portType'; - $this->portTypes[$attrs['name']] = array(); - $this->currentPortType = $attrs['name']; - break; - case "binding": - if (isset($attrs['name'])) { - // get binding name - if (strpos($attrs['name'], ':')) { - $this->currentBinding = $this->getLocalPart($attrs['name']); - } else { - $this->currentBinding = $attrs['name']; - } - $this->status = 'binding'; - $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); - $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); - } - break; - case 'service': - $this->serviceName = $attrs['name']; - $this->status = 'service'; - $this->debug('current service: ' . $this->serviceName); - break; - case 'definitions': - foreach ($attrs as $name => $value) { - $this->wsdl_info[$name] = $value; - } - break; - } - } - } - - /** - * end-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @access private - */ - function end_element($parser, $name){ - // unset schema status - if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { - $this->status = ""; - $this->appendDebug($this->currentSchema->getDebug()); - $this->currentSchema->clearDebug(); - $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; - $this->debug('Parsing WSDL schema done'); - } - if ($this->status == 'schema') { - $this->currentSchema->schemaEndElement($parser, $name); - } else { - // bring depth down a notch - $this->depth--; - } - // end documentation - if ($this->documentation) { - //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. - //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; - $this->documentation = false; - } - } - - /** - * element content handler - * - * @param string $parser XML parser object - * @param string $data element content - * @access private - */ - function character_data($parser, $data) - { - $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; - if (isset($this->message[$pos]['cdata'])) { - $this->message[$pos]['cdata'] .= $data; - } - if ($this->documentation) { - $this->documentation .= $data; - } - } - - function getBindingData($binding) - { - if (is_array($this->bindings[$binding])) { - return $this->bindings[$binding]; - } - } - - /** - * returns an assoc array of operation names => operation data - * - * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) - * @return array - * @access public - */ - function getOperations($bindingType = 'soap') - { - $ops = array(); - if ($bindingType == 'soap') { - $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; - } - // loop thru ports - foreach($this->ports as $port => $portData) { - // binding type of port matches parameter - if ($portData['bindingType'] == $bindingType) { - //$this->debug("getOperations for port $port"); - //$this->debug("port data: " . $this->varDump($portData)); - //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); - // merge bindings - if (isset($this->bindings[ $portData['binding'] ]['operations'])) { - $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); - } - } - } - return $ops; - } - - /** - * returns an associative array of data necessary for calling an operation - * - * @param string $operation , name of operation - * @param string $bindingType , type of binding eg: soap - * @return array - * @access public - */ - function getOperationData($operation, $bindingType = 'soap') - { - if ($bindingType == 'soap') { - $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; - } - // loop thru ports - foreach($this->ports as $port => $portData) { - // binding type of port matches parameter - if ($portData['bindingType'] == $bindingType) { - // get binding - //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { - foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { - // note that we could/should also check the namespace here - if ($operation == $bOperation) { - $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; - return $opData; - } - } - } - } - } - - /** - * returns an associative array of data necessary for calling an operation - * - * @param string $soapAction soapAction for operation - * @param string $bindingType type of binding eg: soap - * @return array - * @access public - */ - function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { - if ($bindingType == 'soap') { - $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; - } - // loop thru ports - foreach($this->ports as $port => $portData) { - // binding type of port matches parameter - if ($portData['bindingType'] == $bindingType) { - // loop through operations for the binding - foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { - if ($opData['soapAction'] == $soapAction) { - return $opData; - } - } - } - } - } - - /** - * returns an array of information about a given type - * returns false if no type exists by the given name - * - * typeDef = array( - * 'elements' => array(), // refs to elements array - * 'restrictionBase' => '', - * 'phpType' => '', - * 'order' => '(sequence|all)', - * 'attrs' => array() // refs to attributes array - * ) - * - * @param $type string the type - * @param $ns string namespace (not prefix) of the type - * @return mixed - * @access public - * @see xmlschema - */ - function getTypeDef($type, $ns) { - $this->debug("in getTypeDef: type=$type, ns=$ns"); - if ((! $ns) && isset($this->namespaces['tns'])) { - $ns = $this->namespaces['tns']; - $this->debug("in getTypeDef: type namespace forced to $ns"); - } - if (isset($this->schemas[$ns])) { - $this->debug("in getTypeDef: have schema for namespace $ns"); - for ($i = 0; $i < count($this->schemas[$ns]); $i++) { - $xs = &$this->schemas[$ns][$i]; - $t = $xs->getTypeDef($type); - $this->appendDebug($xs->getDebug()); - $xs->clearDebug(); - if ($t) { - if (!isset($t['phpType'])) { - // get info for type to tack onto the element - $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); - $ns = substr($t['type'], 0, strrpos($t['type'], ':')); - $etype = $this->getTypeDef($uqType, $ns); - if ($etype) { - $this->debug("found type for [element] $type:"); - $this->debug($this->varDump($etype)); - if (isset($etype['phpType'])) { - $t['phpType'] = $etype['phpType']; - } - if (isset($etype['elements'])) { - $t['elements'] = $etype['elements']; - } - if (isset($etype['attrs'])) { - $t['attrs'] = $etype['attrs']; - } - } - } - return $t; - } - } - } else { - $this->debug("in getTypeDef: do not have schema for namespace $ns"); - } - return false; - } - - /** - * prints html description of services - * - * @access private - */ - function webDescription(){ - global $HTTP_SERVER_VARS; - - if (isset($_SERVER)) { - $PHP_SELF = $_SERVER['PHP_SELF']; - } elseif (isset($HTTP_SERVER_VARS)) { - $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; - } else { - $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); - } - - $b = ' - <html><head><title>NuSOAP: '.$this->serviceName.'</title> - <style type="text/css"> - body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } - p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } - pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} - ul { margin-top: 10px; margin-left: 20px; } - li { list-style-type: none; margin-top: 10px; color: #000000; } - .content{ - margin-left: 0px; padding-bottom: 2em; } - .nav { - padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; - margin-top: 10px; margin-left: 0px; color: #000000; - background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } - .title { - font-family: arial; font-size: 26px; color: #ffffff; - background-color: #999999; width: 105%; margin-left: 0px; - padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} - .hidden { - position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; - font-family: arial; overflow: hidden; width: 600; - padding: 20px; font-size: 10px; background-color: #999999; - layer-background-color:#FFFFFF; } - a,a:active { color: charcoal; font-weight: bold; } - a:visited { color: #666666; font-weight: bold; } - a:hover { color: cc3300; font-weight: bold; } - </style> - <script language="JavaScript" type="text/javascript"> - <!-- - // POP-UP CAPTIONS... - function lib_bwcheck(){ //Browsercheck (needed) - this.ver=navigator.appVersion - this.agent=navigator.userAgent - this.dom=document.getElementById?1:0 - this.opera5=this.agent.indexOf("Opera 5")>-1 - this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; - this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; - this.ie4=(document.all && !this.dom && !this.opera5)?1:0; - this.ie=this.ie4||this.ie5||this.ie6 - this.mac=this.agent.indexOf("Mac")>-1 - this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; - this.ns4=(document.layers && !this.dom)?1:0; - this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) - return this - } - var bw = new lib_bwcheck() - //Makes crossbrowser object. - function makeObj(obj){ - this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; - if(!this.evnt) return false - this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; - this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; - this.writeIt=b_writeIt; - return this - } - // A unit of measure that will be added when setting the position of a layer. - //var px = bw.ns4||window.opera?"":"px"; - function b_writeIt(text){ - if (bw.ns4){this.wref.write(text);this.wref.close()} - else this.wref.innerHTML = text - } - //Shows the messages - var oDesc; - function popup(divid){ - if(oDesc = new makeObj(divid)){ - oDesc.css.visibility = "visible" - } - } - function popout(){ // Hides message - if(oDesc) oDesc.css.visibility = "hidden" - } - //--> - </script> - </head> - <body> - <div class=content> - <br><br> - <div class=title>'.$this->serviceName.'</div> - <div class=nav> - <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service. - Click on an operation name to view it's details.</p> - <ul>'; - foreach($this->getOperations() as $op => $data){ - $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>"; - // create hidden div - $b .= "<div id='$op' class='hidden'> - <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>"; - foreach($data as $donnie => $marie){ // loop through opdata - if($donnie == 'input' || $donnie == 'output'){ // show input/output data - $b .= "<font color='white'>".ucfirst($donnie).':</font><br>'; - foreach($marie as $captain => $tenille){ // loop through data - if($captain == 'parts'){ // loop thru parts - $b .= " $captain:<br>"; - //if(is_array($tenille)){ - foreach($tenille as $joanie => $chachi){ - $b .= " $joanie: $chachi<br>"; - } - //} - } else { - $b .= " $captain: $tenille<br>"; - } - } - } else { - $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>"; - } - } - $b .= '</div>'; - } - $b .= ' - <ul> - </div> - </div></body></html>'; - return $b; - } - - /** - * serialize the parsed wsdl - * - * @param mixed $debug whether to put debug=1 in endpoint URL - * @return string serialization of WSDL - * @access public - */ - function serialize($debug = 0) - { - $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'; - $xml .= "\n<definitions"; - foreach($this->namespaces as $k => $v) { - $xml .= " xmlns:$k=\"$v\""; - } - // 10.9.02 - add poulter fix for wsdl and tns declarations - if (isset($this->namespaces['wsdl'])) { - $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; - } - if (isset($this->namespaces['tns'])) { - $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; - } - $xml .= '>'; - // imports - if (sizeof($this->import) > 0) { - foreach($this->import as $ns => $list) { - foreach ($list as $ii) { - if ($ii['location'] != '') { - $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />'; - } else { - $xml .= '<import namespace="' . $ns . '" />'; - } - } - } - } - // types - if (count($this->schemas)>=1) { - $xml .= "\n<types>"; - foreach ($this->schemas as $ns => $list) { - foreach ($list as $xs) { - $xml .= $xs->serializeSchema(); - } - } - $xml .= '</types>'; - } - // messages - if (count($this->messages) >= 1) { - foreach($this->messages as $msgName => $msgParts) { - $xml .= "\n<message name=\"" . $msgName . '">'; - if(is_array($msgParts)){ - foreach($msgParts as $partName => $partType) { - // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>'; - if (strpos($partType, ':')) { - $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); - } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { - // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>'; - $typePrefix = 'xsd'; - } else { - foreach($this->typemap as $ns => $types) { - if (isset($types[$partType])) { - $typePrefix = $this->getPrefixFromNamespace($ns); - } - } - if (!isset($typePrefix)) { - die("$partType has no namespace!"); - } - } - $ns = $this->getNamespaceFromPrefix($typePrefix); - $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); - if ($typeDef['typeClass'] == 'element') { - $elementortype = 'element'; - } else { - $elementortype = 'type'; - } - $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />'; - } - } - $xml .= '</message>'; - } - } - // bindings & porttypes - if (count($this->bindings) >= 1) { - $binding_xml = ''; - $portType_xml = ''; - foreach($this->bindings as $bindingName => $attrs) { - $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">'; - $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>'; - $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">'; - foreach($attrs['operations'] as $opName => $opParts) { - $binding_xml .= '<operation name="' . $opName . '">'; - $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>'; - if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { - $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; - } else { - $enc_style = ''; - } - $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>'; - if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { - $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; - } else { - $enc_style = ''; - } - $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>'; - $binding_xml .= '</operation>'; - $portType_xml .= '<operation name="' . $opParts['name'] . '"'; - if (isset($opParts['parameterOrder'])) { - $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"'; - } - $portType_xml .= '>'; - if(isset($opParts['documentation']) && $opParts['documentation'] != '') { - $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>'; - } - $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>'; - $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>'; - $portType_xml .= '</operation>'; - } - $portType_xml .= '</portType>'; - $binding_xml .= '</binding>'; - } - $xml .= $portType_xml . $binding_xml; - } - // services - $xml .= "\n<service name=\"" . $this->serviceName . '">'; - if (count($this->ports) >= 1) { - foreach($this->ports as $pName => $attrs) { - $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">'; - $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>'; - $xml .= '</port>'; - } - } - $xml .= '</service>'; - return $xml . "\n</definitions>"; - } - - /** - * serialize PHP values according to a WSDL message definition - * - * TODO - * - multi-ref serialization - * - validate PHP values against type definitions, return errors if invalid - * - * @param string $operation operation name - * @param string $direction (input|output) - * @param mixed $parameters parameter value(s) - * @return mixed parameters serialized as XML or false on error (e.g. operation not found) - * @access public - */ - function serializeRPCParameters($operation, $direction, $parameters) - { - $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); - $this->appendDebug('parameters=' . $this->varDump($parameters)); - - if ($direction != 'input' && $direction != 'output') { - $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); - $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); - return false; - } - if (!$opData = $this->getOperationData($operation)) { - $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); - $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); - return false; - } - $this->debug('opData:'); - $this->appendDebug($this->varDump($opData)); - - // Get encoding style for output and set to current - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { - $encodingStyle = $opData['output']['encodingStyle']; - $enc_style = $encodingStyle; - } - - // set input params - $xml = ''; - if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { - - $use = $opData[$direction]['use']; - $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); - if (is_array($parameters)) { - $parametersArrayType = $this->isArraySimpleOrStruct($parameters); - $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); - foreach($opData[$direction]['parts'] as $name => $type) { - $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); - // Track encoding style - if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { - $encodingStyle = $opData[$direction]['encodingStyle']; - $enc_style = $encodingStyle; - } else { - $enc_style = false; - } - // NOTE: add error handling here - // if serializeType returns false, then catch global error and fault - if ($parametersArrayType == 'arraySimple') { - $p = array_shift($parameters); - $this->debug('calling serializeType w/indexed param'); - $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); - } elseif (isset($parameters[$name])) { - $this->debug('calling serializeType w/named param'); - $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); - } else { - // TODO: only send nillable - $this->debug('calling serializeType w/null param'); - $xml .= $this->serializeType($name, $type, null, $use, $enc_style); - } - } - } else { - $this->debug('no parameters passed.'); - } - } - $this->debug("serializeRPCParameters returning: $xml"); - return $xml; - } - - /** - * serialize a PHP value according to a WSDL message definition - * - * TODO - * - multi-ref serialization - * - validate PHP values against type definitions, return errors if invalid - * - * @param string $ type name - * @param mixed $ param value - * @return mixed new param or false if initial value didn't validate - * @access public - * @deprecated - */ - function serializeParameters($operation, $direction, $parameters) - { - $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); - $this->appendDebug('parameters=' . $this->varDump($parameters)); - - if ($direction != 'input' && $direction != 'output') { - $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); - $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); - return false; - } - if (!$opData = $this->getOperationData($operation)) { - $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); - $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); - return false; - } - $this->debug('opData:'); - $this->appendDebug($this->varDump($opData)); - - // Get encoding style for output and set to current - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { - $encodingStyle = $opData['output']['encodingStyle']; - $enc_style = $encodingStyle; - } - - // set input params - $xml = ''; - if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { - - $use = $opData[$direction]['use']; - $this->debug("use=$use"); - $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); - if (is_array($parameters)) { - $parametersArrayType = $this->isArraySimpleOrStruct($parameters); - $this->debug('have ' . $parametersArrayType . ' parameters'); - foreach($opData[$direction]['parts'] as $name => $type) { - $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); - // Track encoding style - if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { - $encodingStyle = $opData[$direction]['encodingStyle']; - $enc_style = $encodingStyle; - } else { - $enc_style = false; - } - // NOTE: add error handling here - // if serializeType returns false, then catch global error and fault - if ($parametersArrayType == 'arraySimple') { - $p = array_shift($parameters); - $this->debug('calling serializeType w/indexed param'); - $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); - } elseif (isset($parameters[$name])) { - $this->debug('calling serializeType w/named param'); - $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); - } else { - // TODO: only send nillable - $this->debug('calling serializeType w/null param'); - $xml .= $this->serializeType($name, $type, null, $use, $enc_style); - } - } - } else { - $this->debug('no parameters passed.'); - } - } - $this->debug("serializeParameters returning: $xml"); - return $xml; - } - - /** - * serializes a PHP value according a given type definition - * - * @param string $name name of value (part or element) - * @param string $type XML schema type of value (type or element) - * @param mixed $value a native PHP value (parameter value) - * @param string $use use for part (encoded|literal) - * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) - * @param boolean $unqualified a kludge for what should be XML namespace form handling - * @return string value serialized as an XML string - * @access private - */ - function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) - { - $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); - $this->appendDebug("value=" . $this->varDump($value)); - if($use == 'encoded' && $encodingStyle) { - $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; - } - - // if a soapval has been supplied, let its type override the WSDL - if (is_object($value) && get_class($value) == 'soapval') { - if ($value->type_ns) { - $type = $value->type_ns . ':' . $value->type; - $forceType = true; - $this->debug("in serializeType: soapval overrides type to $type"); - } elseif ($value->type) { - $type = $value->type; - $forceType = true; - $this->debug("in serializeType: soapval overrides type to $type"); - } else { - $forceType = false; - $this->debug("in serializeType: soapval does not override type"); - } - $attrs = $value->attributes; - $value = $value->value; - $this->debug("in serializeType: soapval overrides value to $value"); - if ($attrs) { - if (!is_array($value)) { - $value['!'] = $value; - } - foreach ($attrs as $n => $v) { - $value['!' . $n] = $v; - } - $this->debug("in serializeType: soapval provides attributes"); - } - } else { - $forceType = false; - } - - $xml = ''; - if (strpos($type, ':')) { - $uqType = substr($type, strrpos($type, ':') + 1); - $ns = substr($type, 0, strrpos($type, ':')); - $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); - if ($this->getNamespaceFromPrefix($ns)) { - $ns = $this->getNamespaceFromPrefix($ns); - $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); - } - - if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ - $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); - if ($unqualified && $use == 'literal') { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - if (is_null($value)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - $xml = "<$name$elementNS/>"; - } else { - // TODO: depends on nillable, which should be checked before calling this method - $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - if ($uqType == 'boolean') { - if ((is_string($value) && $value == 'false') || (! $value)) { - $value = 'false'; - } else { - $value = 'true'; - } - } - if ($uqType == 'string' && gettype($value) == 'string') { - $value = $this->expandEntities($value); - } - if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { - $value = sprintf("%.0lf", $value); - } - // it's a scalar - // TODO: what about null/nil values? - // check type isn't a custom type extending xmlschema namespace - if (!$this->getTypeDef($uqType, $ns)) { - if ($use == 'literal') { - if ($forceType) { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; - } else { - $xml = "<$name$elementNS>$value</$name>"; - } - } else { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); - } else if ($ns == 'http://xml.apache.org/xml-soap') { - $this->debug('in serializeType: appears to be Apache SOAP type'); - if ($uqType == 'Map') { - $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); - if (! $tt_prefix) { - $this->debug('in serializeType: Add namespace for Apache SOAP type'); - $tt_prefix = 'ns' . rand(1000, 9999); - $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; - // force this to be added to usedNamespaces - $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); - } - $contents = ''; - foreach($value as $k => $v) { - $this->debug("serializing map element: key $k, value $v"); - $contents .= '<item>'; - $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); - $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); - $contents .= '</item>'; - } - if ($use == 'literal') { - if ($forceType) { - $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>"; - } else { - $xml = "<$name>$contents</$name>"; - } - } else { - $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - $this->debug('in serializeType: Apache SOAP type, but only support Map'); - } - } else { - // TODO: should the type be compared to types in XSD, and the namespace - // set to XSD if the type matches? - $this->debug("in serializeType: No namespace for type $type"); - $ns = ''; - $uqType = $type; - } - if(!$typeDef = $this->getTypeDef($uqType, $ns)){ - $this->setError("$type ($uqType) is not a supported type."); - $this->debug("in serializeType: $type ($uqType) is not a supported type."); - return false; - } else { - $this->debug("in serializeType: found typeDef"); - $this->appendDebug('typeDef=' . $this->varDump($typeDef)); - } - $phpType = $typeDef['phpType']; - $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); - // if php type == struct, map value to the <all> element names - if ($phpType == 'struct') { - if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { - $elementName = $uqType; - if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { - $elementNS = " xmlns=\"$ns\""; - } else { - $elementNS = " xmlns=\"\""; - } - } else { - $elementName = $name; - if ($unqualified) { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - } - if (is_null($value)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - $xml = "<$elementName$elementNS/>"; - } else { - $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - if (is_object($value)) { - $value = get_object_vars($value); - } - if (is_array($value)) { - $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); - if ($use == 'literal') { - if ($forceType) { - $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; - } else { - $xml = "<$elementName$elementNS$elementAttrs>"; - } - } else { - $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; - } - - $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); - $xml .= "</$elementName>"; - } else { - $this->debug("in serializeType: phpType is struct, but value is not an array"); - $this->setError("phpType is struct, but value is not an array: see debug output for details"); - $xml = ''; - } - } elseif ($phpType == 'array') { - if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { - $elementNS = " xmlns=\"$ns\""; - } else { - if ($unqualified) { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - } - if (is_null($value)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - $xml = "<$name$elementNS/>"; - } else { - $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . - $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . - ":Array\" " . - $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . - ':arrayType="' . - $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . - ':' . - $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - if (isset($typeDef['multidimensional'])) { - $nv = array(); - foreach($value as $v) { - $cols = ',' . sizeof($v); - $nv = array_merge($nv, $v); - } - $value = $nv; - } else { - $cols = ''; - } - if (is_array($value) && sizeof($value) >= 1) { - $rows = sizeof($value); - $contents = ''; - foreach($value as $k => $v) { - $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); - //if (strpos($typeDef['arrayType'], ':') ) { - if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { - $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); - } else { - $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); - } - } - } else { - $rows = 0; - $contents = null; - } - // TODO: for now, an empty value will be serialized as a zero element - // array. Revisit this when coding the handling of null/nil values. - if ($use == 'literal') { - $xml = "<$name$elementNS>" - .$contents - ."</$name>"; - } else { - $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. - $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') - .':arrayType="' - .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) - .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" - .$contents - ."</$name>"; - } - } elseif ($phpType == 'scalar') { - if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { - $elementNS = " xmlns=\"$ns\""; - } else { - if ($unqualified) { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - } - if ($use == 'literal') { - if ($forceType) { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; - } else { - $xml = "<$name$elementNS>$value</$name>"; - } - } else { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; - } - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - - /** - * serializes the attributes for a complexType - * - * @param array $typeDef our internal representation of an XML schema type (or element) - * @param mixed $value a native PHP value (parameter value) - * @param string $ns the namespace of the type - * @param string $uqType the local part of the type - * @return string value serialized as an XML string - * @access private - */ - function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { - $xml = ''; - if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { - $this->debug("serialize attributes for XML Schema type $ns:$uqType"); - if (is_array($value)) { - $xvalue = $value; - } elseif (is_object($value)) { - $xvalue = get_object_vars($value); - } else { - $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); - $xvalue = array(); - } - foreach ($typeDef['attrs'] as $aName => $attrs) { - if (isset($xvalue['!' . $aName])) { - $xname = '!' . $aName; - $this->debug("value provided for attribute $aName with key $xname"); - } elseif (isset($xvalue[$aName])) { - $xname = $aName; - $this->debug("value provided for attribute $aName with key $xname"); - } elseif (isset($attrs['default'])) { - $xname = '!' . $aName; - $xvalue[$xname] = $attrs['default']; - $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); - } else { - $xname = ''; - $this->debug("no value provided for attribute $aName"); - } - if ($xname) { - $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; - } - } - } else { - $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); - } - if (isset($typeDef['extensionBase'])) { - $ns = $this->getPrefix($typeDef['extensionBase']); - $uqType = $this->getLocalPart($typeDef['extensionBase']); - if ($this->getNamespaceFromPrefix($ns)) { - $ns = $this->getNamespaceFromPrefix($ns); - } - if ($typeDef = $this->getTypeDef($uqType, $ns)) { - $this->debug("serialize attributes for extension base $ns:$uqType"); - $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); - } else { - $this->debug("extension base $ns:$uqType is not a supported type"); - } - } - return $xml; - } - - /** - * serializes the elements for a complexType - * - * @param array $typeDef our internal representation of an XML schema type (or element) - * @param mixed $value a native PHP value (parameter value) - * @param string $ns the namespace of the type - * @param string $uqType the local part of the type - * @param string $use use for part (encoded|literal) - * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) - * @return string value serialized as an XML string - * @access private - */ - function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { - $xml = ''; - if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { - $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); - if (is_array($value)) { - $xvalue = $value; - } elseif (is_object($value)) { - $xvalue = get_object_vars($value); - } else { - $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); - $xvalue = array(); - } - // toggle whether all elements are present - ideally should validate against schema - if (count($typeDef['elements']) != count($xvalue)){ - $optionals = true; - } - foreach ($typeDef['elements'] as $eName => $attrs) { - if (!isset($xvalue[$eName])) { - if (isset($attrs['default'])) { - $xvalue[$eName] = $attrs['default']; - $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); - } - } - // if user took advantage of a minOccurs=0, then only serialize named parameters - if (isset($optionals) - && (!isset($xvalue[$eName])) - && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') - ){ - if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { - $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); - } - // do nothing - $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); - } else { - // get value - if (isset($xvalue[$eName])) { - $v = $xvalue[$eName]; - } else { - $v = null; - } - if (isset($attrs['form'])) { - $unqualified = ($attrs['form'] == 'unqualified'); - } else { - $unqualified = false; - } - if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { - $vv = $v; - foreach ($vv as $k => $v) { - if (isset($attrs['type']) || isset($attrs['ref'])) { - // serialize schema-defined type - $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); - } else { - // serialize generic type (can this ever really happen?) - $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); - $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); - } - } - } else { - if (isset($attrs['type']) || isset($attrs['ref'])) { - // serialize schema-defined type - $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); - } else { - // serialize generic type (can this ever really happen?) - $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); - $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); - } - } - } - } - } else { - $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); - } - if (isset($typeDef['extensionBase'])) { - $ns = $this->getPrefix($typeDef['extensionBase']); - $uqType = $this->getLocalPart($typeDef['extensionBase']); - if ($this->getNamespaceFromPrefix($ns)) { - $ns = $this->getNamespaceFromPrefix($ns); - } - if ($typeDef = $this->getTypeDef($uqType, $ns)) { - $this->debug("serialize elements for extension base $ns:$uqType"); - $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); - } else { - $this->debug("extension base $ns:$uqType is not a supported type"); - } - } - return $xml; - } - - /** - * adds an XML Schema complex type to the WSDL types - * - * @param string name - * @param string typeClass (complexType|simpleType|attribute) - * @param string phpType: currently supported are array and struct (php assoc array) - * @param string compositor (all|sequence|choice) - * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param array elements = array ( name => array(name=>'',type=>'') ) - * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) - * @param string arrayType: namespace:name (xsd:string) - * @see xmlschema - * @access public - */ - function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { - if (count($elements) > 0) { - foreach($elements as $n => $e){ - // expand each element - foreach ($e as $k => $v) { - $k = strpos($k,':') ? $this->expandQname($k) : $k; - $v = strpos($v,':') ? $this->expandQname($v) : $v; - $ee[$k] = $v; - } - $eElements[$n] = $ee; - } - $elements = $eElements; - } - - if (count($attrs) > 0) { - foreach($attrs as $n => $a){ - // expand each attribute - foreach ($a as $k => $v) { - $k = strpos($k,':') ? $this->expandQname($k) : $k; - $v = strpos($v,':') ? $this->expandQname($v) : $v; - $aa[$k] = $v; - } - $eAttrs[$n] = $aa; - } - $attrs = $eAttrs; - } - - $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; - $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; - - $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; - $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); - } - - /** - * adds an XML Schema simple type to the WSDL types - * - * @param string $name - * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param string $typeClass (should always be simpleType) - * @param string $phpType (should always be scalar) - * @param array $enumeration array of values - * @see xmlschema - * @access public - */ - function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { - $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; - - $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; - $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); - } - - /** - * adds an element to the WSDL types - * - * @param array $attrs attributes that must include name and type - * @see xmlschema - * @access public - */ - function addElement($attrs) { - $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; - $this->schemas[$typens][0]->addElement($attrs); - } - - /** - * register an operation with the server - * - * @param string $name operation (method) name - * @param array $in assoc array of input values: key = param name, value = param type - * @param array $out assoc array of output values: key = param name, value = param type - * @param string $namespace optional The namespace for the operation - * @param string $soapaction optional The soapaction for the operation - * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically - * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) - * @param string $documentation optional The description to include in the WSDL - * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) - * @access public - */ - function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ - if ($use == 'encoded' && $encodingStyle == '') { - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - } - - if ($style == 'document') { - $elements = array(); - foreach ($in as $n => $t) { - $elements[$n] = array('name' => $n, 'type' => $t); - } - $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); - $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); - $in = array('parameters' => 'tns:' . $name); - - $elements = array(); - foreach ($out as $n => $t) { - $elements[$n] = array('name' => $n, 'type' => $t); - } - $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); - $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); - $out = array('parameters' => 'tns:' . $name . 'Response'); - } - - // get binding - $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = - array( - 'name' => $name, - 'binding' => $this->serviceName . 'Binding', - 'endpoint' => $this->endpoint, - 'soapAction' => $soapaction, - 'style' => $style, - 'input' => array( - 'use' => $use, - 'namespace' => $namespace, - 'encodingStyle' => $encodingStyle, - 'message' => $name . 'Request', - 'parts' => $in), - 'output' => array( - 'use' => $use, - 'namespace' => $namespace, - 'encodingStyle' => $encodingStyle, - 'message' => $name . 'Response', - 'parts' => $out), - 'namespace' => $namespace, - 'transport' => 'http://schemas.xmlsoap.org/soap/http', - 'documentation' => $documentation); - // add portTypes - // add messages - if($in) - { - foreach($in as $pName => $pType) - { - if(strpos($pType,':')) { - $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); - } - $this->messages[$name.'Request'][$pName] = $pType; - } - } else { - $this->messages[$name.'Request']= '0'; - } - if($out) - { - foreach($out as $pName => $pType) - { - if(strpos($pType,':')) { - $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); - } - $this->messages[$name.'Response'][$pName] = $pType; - } - } else { - $this->messages[$name.'Response']= '0'; - } - return true; - } -} - +<?php + + + + +/** +* parses a WSDL file, allows access to it's data, other utility methods +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class wsdl extends nusoap_base { + // URL or filename of the root of this WSDL + var $wsdl; + // define internal arrays of bindings, ports, operations, messages, etc. + var $schemas = array(); + var $currentSchema; + var $message = array(); + var $complexTypes = array(); + var $messages = array(); + var $currentMessage; + var $currentOperation; + var $portTypes = array(); + var $currentPortType; + var $bindings = array(); + var $currentBinding; + var $ports = array(); + var $currentPort; + var $opData = array(); + var $status = ''; + var $documentation = false; + var $endpoint = ''; + // array of wsdl docs to import + var $import = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + // for getting wsdl + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $timeout = 0; + var $response_timeout = 30; + + /** + * constructor + * + * @param string $wsdl WSDL document URL + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ + parent::nusoap_base(); + $this->wsdl = $wsdl; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // parse wsdl file + if ($wsdl != "") { + $this->debug('initial wsdl URL: ' . $wsdl); + $this->parseWSDL($wsdl); + } + // imports + // TODO: handle imports more properly, grabbing them in-line and nesting them + $imported_urls = array(); + $imported = 1; + while ($imported > 0) { + $imported = 0; + // Schema imports + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($xs->imports as $ns2 => $list2) { + for ($ii = 0; $ii < count($list2); $ii++) { + if (! $list2[$ii]['loaded']) { + $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; + $url = $list2[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + } + // WSDL imports + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($this->import as $ns => $list) { + for ($ii = 0; $ii < count($list); $ii++) { + if (! $list[$ii]['loaded']) { + $this->import[$ns][$ii]['loaded'] = true; + $url = $list[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + // add new data to operation data + foreach($this->bindings as $binding => $bindingData) { + if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { + foreach($bindingData['operations'] as $operation => $data) { + $this->debug('post-parse data gathering for ' . $operation); + $this->bindings[$binding]['operations'][$operation]['input'] = + isset($this->bindings[$binding]['operations'][$operation]['input']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['input']; + $this->bindings[$binding]['operations'][$operation]['output'] = + isset($this->bindings[$binding]['operations'][$operation]['output']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['output']; + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; + } + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; + } + if (isset($bindingData['style'])) { + $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; + } + $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; + $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; + $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; + } + } + } + } + + /** + * parses the wsdl document + * + * @param string $wsdl path or URL + * @access private + */ + function parseWSDL($wsdl = '') + { + if ($wsdl == '') { + $this->debug('no wsdl passed to parseWSDL()!!'); + $this->setError('no wsdl passed to parseWSDL()!!'); + return false; + } + + // parse $wsdl for url format + $wsdl_props = parse_url($wsdl); + + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { + $this->debug('getting WSDL http(s) URL ' . $wsdl); + // get wsdl + $tr = new soap_transport_http($wsdl); + $tr->request_method = 'GET'; + $tr->useSOAPAction = false; + if($this->proxyhost && $this->proxyport){ + $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + $tr->setEncoding('gzip, deflate'); + $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); + //$this->debug("WSDL request\n" . $tr->outgoing_payload); + //$this->debug("WSDL response\n" . $tr->incoming_payload); + $this->appendDebug($tr->getDebug()); + // catch errors + if($err = $tr->getError() ){ + $errstr = 'HTTP ERROR: '.$err; + $this->debug($errstr); + $this->setError($errstr); + unset($tr); + return false; + } + unset($tr); + $this->debug("got WSDL URL"); + } else { + // $wsdl is not http(s), so treat it as a file URL or plain file path + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { + $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; + } else { + $path = $wsdl; + } + $this->debug('getting WSDL file ' . $path); + if ($fp = @fopen($path, 'r')) { + $wsdl_string = ''; + while ($data = fread($fp, 32768)) { + $wsdl_string .= $data; + } + fclose($fp); + } else { + $errstr = "Bad path to WSDL file $path"; + $this->debug($errstr); + $this->setError($errstr); + return false; + } + } + $this->debug('Parse WSDL'); + // end new code added + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element', 'end_element'); + xml_set_character_data_handler($this->parser, 'character_data'); + // Parse the XML file. + if (!xml_parse($this->parser, $wsdl_string, true)) { + // Display an error message. + $errstr = sprintf( + 'XML error parsing WSDL from %s on line %d: %s', + $wsdl, + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $wsdl_string); + $this->setError($errstr); + return false; + } + // free the parser + xml_parser_free($this->parser); + $this->debug('Parsing WSDL done'); + // catch wsdl parse errors + if($this->getError()){ + return false; + } + return true; + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) + { + if ($this->status == 'schema') { + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } elseif (ereg('schema$', $name)) { + $this->debug('Parsing WSDL schema'); + // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); + $this->status = 'schema'; + $this->currentSchema = new xmlschema('', '', $this->namespaces); + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } else { + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + // process attributes + if (count($attrs) > 0) { + // register namespace declarations + foreach($attrs as $k => $v) { + if (ereg("^xmlns", $k)) { + if ($ns_prefix = substr(strrchr($k, ':'), 1)) { + $this->namespaces[$ns_prefix] = $v; + } else { + $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; + } + if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v . '-instance'; + } + } + } + // expand each attribute prefix to its namespace + foreach($attrs as $k => $v) { + $k = strpos($k, ':') ? $this->expandQname($k) : $k; + if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { + $v = strpos($v, ':') ? $this->expandQname($v) : $v; + } + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // get element prefix, namespace and name + if (ereg(':', $name)) { + // get ns prefix + $prefix = substr($name, 0, strpos($name, ':')); + // get ns + $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; + // get unqualified name + $name = substr(strstr($name, ':'), 1); + } + // process attributes, expanding any prefixes to namespaces + // find status, register data + switch ($this->status) { + case 'message': + if ($name == 'part') { + if (isset($attrs['type'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; + } + if (isset($attrs['element'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; + } + } + break; + case 'portType': + switch ($name) { + case 'operation': + $this->currentPortOperation = $attrs['name']; + $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); + if (isset($attrs['parameterOrder'])) { + $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; + } + break; + case 'documentation': + $this->documentation = true; + break; + // merge input/output data + default: + $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; + $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; + break; + } + break; + case 'binding': + switch ($name) { + case 'binding': + // get ns prefix + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['prefix'] = $prefix; + } + $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); + break; + case 'header': + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; + break; + case 'operation': + if (isset($attrs['soapAction'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; + } + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; + } + if (isset($attrs['name'])) { + $this->currentOperation = $attrs['name']; + $this->debug("current binding operation: $this->currentOperation"); + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; + } + break; + case 'input': + $this->opStatus = 'input'; + break; + case 'output': + $this->opStatus = 'output'; + break; + case 'body': + if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); + } else { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; + } + break; + } + break; + case 'service': + switch ($name) { + case 'port': + $this->currentPort = $attrs['name']; + $this->debug('current port: ' . $this->currentPort); + $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); + + break; + case 'address': + $this->ports[$this->currentPort]['location'] = $attrs['location']; + $this->ports[$this->currentPort]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; + break; + } + break; + } + // set status + switch ($name) { + case 'import': + if (isset($attrs['location'])) { + $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); + $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); + } else { + $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); + } + break; + //wait for schema + //case 'types': + // $this->status = 'schema'; + // break; + case 'message': + $this->status = 'message'; + $this->messages[$attrs['name']] = array(); + $this->currentMessage = $attrs['name']; + break; + case 'portType': + $this->status = 'portType'; + $this->portTypes[$attrs['name']] = array(); + $this->currentPortType = $attrs['name']; + break; + case "binding": + if (isset($attrs['name'])) { + // get binding name + if (strpos($attrs['name'], ':')) { + $this->currentBinding = $this->getLocalPart($attrs['name']); + } else { + $this->currentBinding = $attrs['name']; + } + $this->status = 'binding'; + $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); + $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); + } + break; + case 'service': + $this->serviceName = $attrs['name']; + $this->status = 'service'; + $this->debug('current service: ' . $this->serviceName); + break; + case 'definitions': + foreach ($attrs as $name => $value) { + $this->wsdl_info[$name] = $value; + } + break; + } + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name){ + // unset schema status + if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { + $this->status = ""; + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; + $this->debug('Parsing WSDL schema done'); + } + if ($this->status == 'schema') { + $this->currentSchema->schemaEndElement($parser, $name); + } else { + // bring depth down a notch + $this->depth--; + } + // end documentation + if ($this->documentation) { + //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. + //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; + $this->documentation = false; + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data) + { + $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; + if (isset($this->message[$pos]['cdata'])) { + $this->message[$pos]['cdata'] .= $data; + } + if ($this->documentation) { + $this->documentation .= $data; + } + } + + function getBindingData($binding) + { + if (is_array($this->bindings[$binding])) { + return $this->bindings[$binding]; + } + } + + /** + * returns an assoc array of operation names => operation data + * + * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) + * @return array + * @access public + */ + function getOperations($bindingType = 'soap') + { + $ops = array(); + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + //$this->debug("getOperations for port $port"); + //$this->debug("port data: " . $this->varDump($portData)); + //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); + // merge bindings + if (isset($this->bindings[ $portData['binding'] ]['operations'])) { + $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); + } + } + } + return $ops; + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $operation , name of operation + * @param string $bindingType , type of binding eg: soap + * @return array + * @access public + */ + function getOperationData($operation, $bindingType = 'soap') + { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // get binding + //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { + // note that we could/should also check the namespace here + if ($operation == $bOperation) { + $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; + return $opData; + } + } + } + } + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $soapAction soapAction for operation + * @param string $bindingType type of binding eg: soap + * @return array + * @access public + */ + function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // loop through operations for the binding + foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + if ($opData['soapAction'] == $soapAction) { + return $opData; + } + } + } + } + } + + /** + * returns an array of information about a given type + * returns false if no type exists by the given name + * + * typeDef = array( + * 'elements' => array(), // refs to elements array + * 'restrictionBase' => '', + * 'phpType' => '', + * 'order' => '(sequence|all)', + * 'attrs' => array() // refs to attributes array + * ) + * + * @param $type string the type + * @param $ns string namespace (not prefix) of the type + * @return mixed + * @access public + * @see xmlschema + */ + function getTypeDef($type, $ns) { + $this->debug("in getTypeDef: type=$type, ns=$ns"); + if ((! $ns) && isset($this->namespaces['tns'])) { + $ns = $this->namespaces['tns']; + $this->debug("in getTypeDef: type namespace forced to $ns"); + } + if (isset($this->schemas[$ns])) { + $this->debug("in getTypeDef: have schema for namespace $ns"); + for ($i = 0; $i < count($this->schemas[$ns]); $i++) { + $xs = &$this->schemas[$ns][$i]; + $t = $xs->getTypeDef($type); + $this->appendDebug($xs->getDebug()); + $xs->clearDebug(); + if ($t) { + if (!isset($t['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); + $ns = substr($t['type'], 0, strrpos($t['type'], ':')); + $etype = $this->getTypeDef($uqType, $ns); + if ($etype) { + $this->debug("found type for [element] $type:"); + $this->debug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $t['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $t['elements'] = $etype['elements']; + } + if (isset($etype['attrs'])) { + $t['attrs'] = $etype['attrs']; + } + } + } + return $t; + } + } + } else { + $this->debug("in getTypeDef: do not have schema for namespace $ns"); + } + return false; + } + + /** + * prints html description of services + * + * @access private + */ + function webDescription(){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $PHP_SELF = $_SERVER['PHP_SELF']; + } elseif (isset($HTTP_SERVER_VARS)) { + $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + + $b = ' + <html><head><title>NuSOAP: '.$this->serviceName.'</title> + <style type="text/css"> + body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } + p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } + pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} + ul { margin-top: 10px; margin-left: 20px; } + li { list-style-type: none; margin-top: 10px; color: #000000; } + .content{ + margin-left: 0px; padding-bottom: 2em; } + .nav { + padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; + margin-top: 10px; margin-left: 0px; color: #000000; + background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } + .title { + font-family: arial; font-size: 26px; color: #ffffff; + background-color: #999999; width: 105%; margin-left: 0px; + padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} + .hidden { + position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; + font-family: arial; overflow: hidden; width: 600; + padding: 20px; font-size: 10px; background-color: #999999; + layer-background-color:#FFFFFF; } + a,a:active { color: charcoal; font-weight: bold; } + a:visited { color: #666666; font-weight: bold; } + a:hover { color: cc3300; font-weight: bold; } + </style> + <script language="JavaScript" type="text/javascript"> + <!-- + // POP-UP CAPTIONS... + function lib_bwcheck(){ //Browsercheck (needed) + this.ver=navigator.appVersion + this.agent=navigator.userAgent + this.dom=document.getElementById?1:0 + this.opera5=this.agent.indexOf("Opera 5")>-1 + this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; + this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; + this.ie4=(document.all && !this.dom && !this.opera5)?1:0; + this.ie=this.ie4||this.ie5||this.ie6 + this.mac=this.agent.indexOf("Mac")>-1 + this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; + this.ns4=(document.layers && !this.dom)?1:0; + this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) + return this + } + var bw = new lib_bwcheck() + //Makes crossbrowser object. + function makeObj(obj){ + this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; + if(!this.evnt) return false + this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; + this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; + this.writeIt=b_writeIt; + return this + } + // A unit of measure that will be added when setting the position of a layer. + //var px = bw.ns4||window.opera?"":"px"; + function b_writeIt(text){ + if (bw.ns4){this.wref.write(text);this.wref.close()} + else this.wref.innerHTML = text + } + //Shows the messages + var oDesc; + function popup(divid){ + if(oDesc = new makeObj(divid)){ + oDesc.css.visibility = "visible" + } + } + function popout(){ // Hides message + if(oDesc) oDesc.css.visibility = "hidden" + } + //--> + </script> + </head> + <body> + <div class=content> + <br><br> + <div class=title>'.$this->serviceName.'</div> + <div class=nav> + <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service. + Click on an operation name to view it's details.</p> + <ul>'; + foreach($this->getOperations() as $op => $data){ + $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>"; + // create hidden div + $b .= "<div id='$op' class='hidden'> + <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>"; + foreach($data as $donnie => $marie){ // loop through opdata + if($donnie == 'input' || $donnie == 'output'){ // show input/output data + $b .= "<font color='white'>".ucfirst($donnie).':</font><br>'; + foreach($marie as $captain => $tenille){ // loop through data + if($captain == 'parts'){ // loop thru parts + $b .= " $captain:<br>"; + //if(is_array($tenille)){ + foreach($tenille as $joanie => $chachi){ + $b .= " $joanie: $chachi<br>"; + } + //} + } else { + $b .= " $captain: $tenille<br>"; + } + } + } else { + $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>"; + } + } + $b .= '</div>'; + } + $b .= ' + <ul> + </div> + </div></body></html>'; + return $b; + } + + /** + * serialize the parsed wsdl + * + * @param mixed $debug whether to put debug=1 in endpoint URL + * @return string serialization of WSDL + * @access public + */ + function serialize($debug = 0) + { + $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'; + $xml .= "\n<definitions"; + foreach($this->namespaces as $k => $v) { + $xml .= " xmlns:$k=\"$v\""; + } + // 10.9.02 - add poulter fix for wsdl and tns declarations + if (isset($this->namespaces['wsdl'])) { + $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; + } + if (isset($this->namespaces['tns'])) { + $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; + } + $xml .= '>'; + // imports + if (sizeof($this->import) > 0) { + foreach($this->import as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />'; + } else { + $xml .= '<import namespace="' . $ns . '" />'; + } + } + } + } + // types + if (count($this->schemas)>=1) { + $xml .= "\n<types>"; + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $xml .= $xs->serializeSchema(); + } + } + $xml .= '</types>'; + } + // messages + if (count($this->messages) >= 1) { + foreach($this->messages as $msgName => $msgParts) { + $xml .= "\n<message name=\"" . $msgName . '">'; + if(is_array($msgParts)){ + foreach($msgParts as $partName => $partType) { + // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>'; + if (strpos($partType, ':')) { + $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); + } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { + // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>'; + $typePrefix = 'xsd'; + } else { + foreach($this->typemap as $ns => $types) { + if (isset($types[$partType])) { + $typePrefix = $this->getPrefixFromNamespace($ns); + } + } + if (!isset($typePrefix)) { + die("$partType has no namespace!"); + } + } + $ns = $this->getNamespaceFromPrefix($typePrefix); + $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); + if ($typeDef['typeClass'] == 'element') { + $elementortype = 'element'; + } else { + $elementortype = 'type'; + } + $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />'; + } + } + $xml .= '</message>'; + } + } + // bindings & porttypes + if (count($this->bindings) >= 1) { + $binding_xml = ''; + $portType_xml = ''; + foreach($this->bindings as $bindingName => $attrs) { + $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">'; + $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>'; + $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">'; + foreach($attrs['operations'] as $opName => $opParts) { + $binding_xml .= '<operation name="' . $opName . '">'; + $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>'; + if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>'; + if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>'; + $binding_xml .= '</operation>'; + $portType_xml .= '<operation name="' . $opParts['name'] . '"'; + if (isset($opParts['parameterOrder'])) { + $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"'; + } + $portType_xml .= '>'; + if(isset($opParts['documentation']) && $opParts['documentation'] != '') { + $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>'; + } + $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>'; + $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>'; + $portType_xml .= '</operation>'; + } + $portType_xml .= '</portType>'; + $binding_xml .= '</binding>'; + } + $xml .= $portType_xml . $binding_xml; + } + // services + $xml .= "\n<service name=\"" . $this->serviceName . '">'; + if (count($this->ports) >= 1) { + foreach($this->ports as $pName => $attrs) { + $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">'; + $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>'; + $xml .= '</port>'; + } + } + $xml .= '</service>'; + return $xml . "\n</definitions>"; + } + + /** + * serialize PHP values according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $operation operation name + * @param string $direction (input|output) + * @param mixed $parameters parameter value(s) + * @return mixed parameters serialized as XML or false on error (e.g. operation not found) + * @access public + */ + function serializeRPCParameters($operation, $direction, $parameters) + { + $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeRPCParameters returning: $xml"); + return $xml; + } + + /** + * serialize a PHP value according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $ type name + * @param mixed $ param value + * @return mixed new param or false if initial value didn't validate + * @access public + * @deprecated + */ + function serializeParameters($operation, $direction, $parameters) + { + $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug("use=$use"); + $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . $parametersArrayType . ' parameters'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeParameters returning: $xml"); + return $xml; + } + + /** + * serializes a PHP value according a given type definition + * + * @param string $name name of value (part or element) + * @param string $type XML schema type of value (type or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @param boolean $unqualified a kludge for what should be XML namespace form handling + * @return string value serialized as an XML string + * @access private + */ + function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) + { + $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); + $this->appendDebug("value=" . $this->varDump($value)); + if($use == 'encoded' && $encodingStyle) { + $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; + } + + // if a soapval has been supplied, let its type override the WSDL + if (is_object($value) && get_class($value) == 'soapval') { + if ($value->type_ns) { + $type = $value->type_ns . ':' . $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } elseif ($value->type) { + $type = $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } else { + $forceType = false; + $this->debug("in serializeType: soapval does not override type"); + } + $attrs = $value->attributes; + $value = $value->value; + $this->debug("in serializeType: soapval overrides value to $value"); + if ($attrs) { + if (!is_array($value)) { + $value['!'] = $value; + } + foreach ($attrs as $n => $v) { + $value['!' . $n] = $v; + } + $this->debug("in serializeType: soapval provides attributes"); + } + } else { + $forceType = false; + } + + $xml = ''; + if (strpos($type, ':')) { + $uqType = substr($type, strrpos($type, ':') + 1); + $ns = substr($type, 0, strrpos($type, ':')); + $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); + } + + if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ + $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); + if ($unqualified && $use == 'literal') { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + // TODO: depends on nillable, which should be checked before calling this method + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if ($uqType == 'boolean') { + if ((is_string($value) && $value == 'false') || (! $value)) { + $value = 'false'; + } else { + $value = 'true'; + } + } + if ($uqType == 'string' && gettype($value) == 'string') { + $value = $this->expandEntities($value); + } + if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { + $value = sprintf("%.0lf", $value); + } + // it's a scalar + // TODO: what about null/nil values? + // check type isn't a custom type extending xmlschema namespace + if (!$this->getTypeDef($uqType, $ns)) { + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; + } else { + $xml = "<$name$elementNS>$value</$name>"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); + } else if ($ns == 'http://xml.apache.org/xml-soap') { + $this->debug('in serializeType: appears to be Apache SOAP type'); + if ($uqType == 'Map') { + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + if (! $tt_prefix) { + $this->debug('in serializeType: Add namespace for Apache SOAP type'); + $tt_prefix = 'ns' . rand(1000, 9999); + $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; + // force this to be added to usedNamespaces + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + } + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing map element: key $k, value $v"); + $contents .= '<item>'; + $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); + $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); + $contents .= '</item>'; + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>"; + } else { + $xml = "<$name>$contents</$name>"; + } + } else { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('in serializeType: Apache SOAP type, but only support Map'); + } + } else { + // TODO: should the type be compared to types in XSD, and the namespace + // set to XSD if the type matches? + $this->debug("in serializeType: No namespace for type $type"); + $ns = ''; + $uqType = $type; + } + if(!$typeDef = $this->getTypeDef($uqType, $ns)){ + $this->setError("$type ($uqType) is not a supported type."); + $this->debug("in serializeType: $type ($uqType) is not a supported type."); + return false; + } else { + $this->debug("in serializeType: found typeDef"); + $this->appendDebug('typeDef=' . $this->varDump($typeDef)); + } + $phpType = $typeDef['phpType']; + $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); + // if php type == struct, map value to the <all> element names + if ($phpType == 'struct') { + if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { + $elementName = $uqType; + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = " xmlns=\"\""; + } + } else { + $elementName = $name; + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$elementName$elementNS/>"; + } else { + $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (is_object($value)) { + $value = get_object_vars($value); + } + if (is_array($value)) { + $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + if ($use == 'literal') { + if ($forceType) { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; + } else { + $xml = "<$elementName$elementNS$elementAttrs>"; + } + } else { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; + } + + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + $xml .= "</$elementName>"; + } else { + $this->debug("in serializeType: phpType is struct, but value is not an array"); + $this->setError("phpType is struct, but value is not an array: see debug output for details"); + $xml = ''; + } + } elseif ($phpType == 'array') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ":Array\" " . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ':arrayType="' . + $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . + ':' . + $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (isset($typeDef['multidimensional'])) { + $nv = array(); + foreach($value as $v) { + $cols = ',' . sizeof($v); + $nv = array_merge($nv, $v); + } + $value = $nv; + } else { + $cols = ''; + } + if (is_array($value) && sizeof($value) >= 1) { + $rows = sizeof($value); + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); + //if (strpos($typeDef['arrayType'], ':') ) { + if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { + $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); + } else { + $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); + } + } + } else { + $rows = 0; + $contents = null; + } + // TODO: for now, an empty value will be serialized as a zero element + // array. Revisit this when coding the handling of null/nil values. + if ($use == 'literal') { + $xml = "<$name$elementNS>" + .$contents + ."</$name>"; + } else { + $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') + .':arrayType="' + .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) + .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" + .$contents + ."</$name>"; + } + } elseif ($phpType == 'scalar') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; + } else { + $xml = "<$name$elementNS>$value</$name>"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; + } + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + + /** + * serializes the attributes for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { + $xml = ''; + if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { + $this->debug("serialize attributes for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + foreach ($typeDef['attrs'] as $aName => $attrs) { + if (isset($xvalue['!' . $aName])) { + $xname = '!' . $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($xvalue[$aName])) { + $xname = $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($attrs['default'])) { + $xname = '!' . $aName; + $xvalue[$xname] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); + } else { + $xname = ''; + $this->debug("no value provided for attribute $aName"); + } + if ($xname) { + $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; + } + } + } else { + $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize attributes for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * serializes the elements for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { + $xml = ''; + if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { + $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + // toggle whether all elements are present - ideally should validate against schema + if (count($typeDef['elements']) != count($xvalue)){ + $optionals = true; + } + foreach ($typeDef['elements'] as $eName => $attrs) { + if (!isset($xvalue[$eName])) { + if (isset($attrs['default'])) { + $xvalue[$eName] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); + } + } + // if user took advantage of a minOccurs=0, then only serialize named parameters + if (isset($optionals) + && (!isset($xvalue[$eName])) + && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') + ){ + if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { + $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); + } + // do nothing + $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); + } else { + // get value + if (isset($xvalue[$eName])) { + $v = $xvalue[$eName]; + } else { + $v = null; + } + if (isset($attrs['form'])) { + $unqualified = ($attrs['form'] == 'unqualified'); + } else { + $unqualified = false; + } + if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { + $vv = $v; + foreach ($vv as $k => $v) { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } else { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } + } + } else { + $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize elements for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * adds an XML Schema complex type to the WSDL types + * + * @param string name + * @param string typeClass (complexType|simpleType|attribute) + * @param string phpType: currently supported are array and struct (php assoc array) + * @param string compositor (all|sequence|choice) + * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param array elements = array ( name => array(name=>'',type=>'') ) + * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) + * @param string arrayType: namespace:name (xsd:string) + * @see xmlschema + * @access public + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { + if (count($elements) > 0) { + foreach($elements as $n => $e){ + // expand each element + foreach ($e as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $ee[$k] = $v; + } + $eElements[$n] = $ee; + } + $elements = $eElements; + } + + if (count($attrs) > 0) { + foreach($attrs as $n => $a){ + // expand each attribute + foreach ($a as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $aa[$k] = $v; + } + $eAttrs[$n] = $aa; + } + $attrs = $eAttrs; + } + + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); + } + + /** + * adds an XML Schema simple type to the WSDL types + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @see xmlschema + * @access public + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); + } + + /** + * adds an element to the WSDL types + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addElement($attrs); + } + + /** + * register an operation with the server + * + * @param string $name operation (method) name + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param string $namespace optional The namespace for the operation + * @param string $soapaction optional The soapaction for the operation + * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) + * @param string $documentation optional The description to include in the WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ + if ($use == 'encoded' && $encodingStyle == '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + if ($style == 'document') { + $elements = array(); + foreach ($in as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); + $in = array('parameters' => 'tns:' . $name); + + $elements = array(); + foreach ($out as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); + $out = array('parameters' => 'tns:' . $name . 'Response'); + } + + // get binding + $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = + array( + 'name' => $name, + 'binding' => $this->serviceName . 'Binding', + 'endpoint' => $this->endpoint, + 'soapAction' => $soapaction, + 'style' => $style, + 'input' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Request', + 'parts' => $in), + 'output' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Response', + 'parts' => $out), + 'namespace' => $namespace, + 'transport' => 'http://schemas.xmlsoap.org/soap/http', + 'documentation' => $documentation); + // add portTypes + // add messages + if($in) + { + foreach($in as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Request'][$pName] = $pType; + } + } else { + $this->messages[$name.'Request']= '0'; + } + if($out) + { + foreach($out as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Response'][$pName] = $pType; + } + } else { + $this->messages[$name.'Response']= '0'; + } + return true; + } +} + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/class.wsdlcache.php b/htdocs/includes/nusoap/lib/class.wsdlcache.php index 54956e5f262ed70aaea3a70e514a0a3494fbd5c8..8326b506d624c9f1d83bad65ad118125ab70656e 100644 --- a/htdocs/includes/nusoap/lib/class.wsdlcache.php +++ b/htdocs/includes/nusoap/lib/class.wsdlcache.php @@ -1,184 +1,184 @@ -<?php - - - -/** -* caches instances of the wsdl class -* -* @author Scott Nichol <snichol@computer.org> -* @author Ingo Fischer <ingo@apollon.de> -* @version $Id$ -* @access public -*/ -class wsdlcache { - /** - * @var resource - * @access private - */ - var $fplock; - /** - * @var integer - * @access private - */ - var $cache_lifetime; - /** - * @var string - * @access private - */ - var $cache_dir; - /** - * @var string - * @access public - */ - var $debug_str = ''; - - /** - * constructor - * - * @param string $cache_dir directory for cache-files - * @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited - * @access public - */ - function wsdlcache($cache_dir='.', $cache_lifetime=0) { - $this->fplock = array(); - $this->cache_dir = $cache_dir != '' ? $cache_dir : '.'; - $this->cache_lifetime = $cache_lifetime; - } - - /** - * creates the filename used to cache a wsdl instance - * - * @param string $wsdl The URL of the wsdl instance - * @return string The filename used to cache the instance - * @access private - */ - function createFilename($wsdl) { - return $this->cache_dir.'/wsdlcache-' . md5($wsdl); - } - - /** - * adds debug data to the class level debug string - * - * @param string $string debug data - * @access private - */ - function debug($string){ - $this->debug_str .= get_class($this).": $string\n"; - } - - /** - * gets a wsdl instance from the cache - * - * @param string $wsdl The URL of the wsdl instance - * @return object wsdl The cached wsdl instance, null if the instance is not in the cache - * @access public - */ - function get($wsdl) { - $filename = $this->createFilename($wsdl); - if ($this->obtainMutex($filename, "r")) { - // check for expired WSDL that must be removed from the cache - if ($this->cache_lifetime > 0) { - if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) { - unlink($filename); - $this->debug("Expired $wsdl ($filename) from cache"); - $this->releaseMutex($filename); - return null; - } - } - // see what there is to return - $fp = @fopen($filename, "r"); - if ($fp) { - $s = implode("", @file($filename)); - fclose($fp); - $this->debug("Got $wsdl ($filename) from cache"); - } else { - $s = null; - $this->debug("$wsdl ($filename) not in cache"); - } - $this->releaseMutex($filename); - return (!is_null($s)) ? unserialize($s) : null; - } else { - $this->debug("Unable to obtain mutex for $filename in get"); - } - return null; - } - - /** - * obtains the local mutex - * - * @param string $filename The Filename of the Cache to lock - * @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode - * @return boolean Lock successfully obtained ?! - * @access private - */ - function obtainMutex($filename, $mode) { - if (isset($this->fplock[md5($filename)])) { - $this->debug("Lock for $filename already exists"); - return false; - } - $this->fplock[md5($filename)] = fopen($filename.".lock", "w"); - if ($mode == "r") { - return flock($this->fplock[md5($filename)], LOCK_SH); - } else { - return flock($this->fplock[md5($filename)], LOCK_EX); - } - } - - /** - * adds a wsdl instance to the cache - * - * @param object wsdl $wsdl_instance The wsdl instance to add - * @return boolean WSDL successfully cached - * @access public - */ - function put($wsdl_instance) { - $filename = $this->createFilename($wsdl_instance->wsdl); - $s = serialize($wsdl_instance); - if ($this->obtainMutex($filename, "w")) { - $fp = fopen($filename, "w"); - fputs($fp, $s); - fclose($fp); - $this->debug("Put $wsdl_instance->wsdl ($filename) in cache"); - $this->releaseMutex($filename); - return true; - } else { - $this->debug("Unable to obtain mutex for $filename in put"); - } - return false; - } - - /** - * releases the local mutex - * - * @param string $filename The Filename of the Cache to lock - * @return boolean Lock successfully released - * @access private - */ - function releaseMutex($filename) { - $ret = flock($this->fplock[md5($filename)], LOCK_UN); - fclose($this->fplock[md5($filename)]); - unset($this->fplock[md5($filename)]); - if (! $ret) { - $this->debug("Not able to release lock for $filename"); - } - return $ret; - } - - /** - * removes a wsdl instance from the cache - * - * @param string $wsdl The URL of the wsdl instance - * @return boolean Whether there was an instance to remove - * @access public - */ - function remove($wsdl) { - $filename = $this->createFilename($wsdl); - // ignore errors obtaining mutex - $this->obtainMutex($filename, "w"); - $ret = unlink($filename); - $this->debug("Removed ($ret) $wsdl ($filename) from cache"); - $this->releaseMutex($filename); - return $ret; - } -} -?> +<?php + + + +/** +* caches instances of the wsdl class +* +* @author Scott Nichol <snichol@computer.org> +* @author Ingo Fischer <ingo@apollon.de> +* @version $Id$ +* @access public +*/ +class wsdlcache { + /** + * @var resource + * @access private + */ + var $fplock; + /** + * @var integer + * @access private + */ + var $cache_lifetime; + /** + * @var string + * @access private + */ + var $cache_dir; + /** + * @var string + * @access public + */ + var $debug_str = ''; + + /** + * constructor + * + * @param string $cache_dir directory for cache-files + * @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited + * @access public + */ + function wsdlcache($cache_dir='.', $cache_lifetime=0) { + $this->fplock = array(); + $this->cache_dir = $cache_dir != '' ? $cache_dir : '.'; + $this->cache_lifetime = $cache_lifetime; + } + + /** + * creates the filename used to cache a wsdl instance + * + * @param string $wsdl The URL of the wsdl instance + * @return string The filename used to cache the instance + * @access private + */ + function createFilename($wsdl) { + return $this->cache_dir.'/wsdlcache-' . md5($wsdl); + } + + /** + * adds debug data to the class level debug string + * + * @param string $string debug data + * @access private + */ + function debug($string){ + $this->debug_str .= get_class($this).": $string\n"; + } + + /** + * gets a wsdl instance from the cache + * + * @param string $wsdl The URL of the wsdl instance + * @return object wsdl The cached wsdl instance, null if the instance is not in the cache + * @access public + */ + function get($wsdl) { + $filename = $this->createFilename($wsdl); + if ($this->obtainMutex($filename, "r")) { + // check for expired WSDL that must be removed from the cache + if ($this->cache_lifetime > 0) { + if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) { + unlink($filename); + $this->debug("Expired $wsdl ($filename) from cache"); + $this->releaseMutex($filename); + return null; + } + } + // see what there is to return + $fp = @fopen($filename, "r"); + if ($fp) { + $s = implode("", @file($filename)); + fclose($fp); + $this->debug("Got $wsdl ($filename) from cache"); + } else { + $s = null; + $this->debug("$wsdl ($filename) not in cache"); + } + $this->releaseMutex($filename); + return (!is_null($s)) ? unserialize($s) : null; + } else { + $this->debug("Unable to obtain mutex for $filename in get"); + } + return null; + } + + /** + * obtains the local mutex + * + * @param string $filename The Filename of the Cache to lock + * @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode + * @return boolean Lock successfully obtained ?! + * @access private + */ + function obtainMutex($filename, $mode) { + if (isset($this->fplock[md5($filename)])) { + $this->debug("Lock for $filename already exists"); + return false; + } + $this->fplock[md5($filename)] = fopen($filename.".lock", "w"); + if ($mode == "r") { + return flock($this->fplock[md5($filename)], LOCK_SH); + } else { + return flock($this->fplock[md5($filename)], LOCK_EX); + } + } + + /** + * adds a wsdl instance to the cache + * + * @param object wsdl $wsdl_instance The wsdl instance to add + * @return boolean WSDL successfully cached + * @access public + */ + function put($wsdl_instance) { + $filename = $this->createFilename($wsdl_instance->wsdl); + $s = serialize($wsdl_instance); + if ($this->obtainMutex($filename, "w")) { + $fp = fopen($filename, "w"); + fputs($fp, $s); + fclose($fp); + $this->debug("Put $wsdl_instance->wsdl ($filename) in cache"); + $this->releaseMutex($filename); + return true; + } else { + $this->debug("Unable to obtain mutex for $filename in put"); + } + return false; + } + + /** + * releases the local mutex + * + * @param string $filename The Filename of the Cache to lock + * @return boolean Lock successfully released + * @access private + */ + function releaseMutex($filename) { + $ret = flock($this->fplock[md5($filename)], LOCK_UN); + fclose($this->fplock[md5($filename)]); + unset($this->fplock[md5($filename)]); + if (! $ret) { + $this->debug("Not able to release lock for $filename"); + } + return $ret; + } + + /** + * removes a wsdl instance from the cache + * + * @param string $wsdl The URL of the wsdl instance + * @return boolean Whether there was an instance to remove + * @access public + */ + function remove($wsdl) { + $filename = $this->createFilename($wsdl); + // ignore errors obtaining mutex + $this->obtainMutex($filename, "w"); + $ret = unlink($filename); + $this->debug("Removed ($ret) $wsdl ($filename) from cache"); + $this->releaseMutex($filename); + return $ret; + } +} +?> diff --git a/htdocs/includes/nusoap/lib/class.xmlschema.php b/htdocs/includes/nusoap/lib/class.xmlschema.php index f390959aa1e89a5d56acf4282a018a741744f286..db1ba0b2c46d5cfb4754f2b1571be028aa476ebd 100644 --- a/htdocs/includes/nusoap/lib/class.xmlschema.php +++ b/htdocs/includes/nusoap/lib/class.xmlschema.php @@ -1,906 +1,906 @@ -<?php - - - - -/** -* parses an XML Schema, allows access to it's data, other utility methods -* no validation... yet. -* very experimental and limited. As is discussed on XML-DEV, I'm one of the people -* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty -* tutorials I refer to :) -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class XMLSchema extends nusoap_base { - - // files - var $schema = ''; - var $xml = ''; - // namespaces - var $enclosingNamespaces; - // schema info - var $schemaInfo = array(); - var $schemaTargetNamespace = ''; - // types, elements, attributes defined by the schema - var $attributes = array(); - var $complexTypes = array(); - var $complexTypeStack = array(); - var $currentComplexType = null; - var $elements = array(); - var $elementStack = array(); - var $currentElement = null; - var $simpleTypes = array(); - var $simpleTypeStack = array(); - var $currentSimpleType = null; - // imports - var $imports = array(); - // parser vars - var $parser; - var $position = 0; - var $depth = 0; - var $depth_array = array(); - var $message = array(); - var $defaultNamespace = array(); - - /** - * constructor - * - * @param string $schema schema document URI - * @param string $xml xml document URI - * @param string $namespaces namespaces defined in enclosing XML - * @access public - */ - function XMLSchema($schema='',$xml='',$namespaces=array()){ - parent::nusoap_base(); - $this->debug('xmlschema class instantiated, inside constructor'); - // files - $this->schema = $schema; - $this->xml = $xml; - - // namespaces - $this->enclosingNamespaces = $namespaces; - $this->namespaces = array_merge($this->namespaces, $namespaces); - - // parse schema file - if($schema != ''){ - $this->debug('initial schema file: '.$schema); - $this->parseFile($schema, 'schema'); - } - - // parse xml file - if($xml != ''){ - $this->debug('initial xml file: '.$xml); - $this->parseFile($xml, 'xml'); - } - - } - - /** - * parse an XML file - * - * @param string $xml, path/URL to XML file - * @param string $type, (schema | xml) - * @return boolean - * @access public - */ - function parseFile($xml,$type){ - // parse xml file - if($xml != ""){ - $xmlStr = @join("",@file($xml)); - if($xmlStr == ""){ - $msg = 'Error reading XML from '.$xml; - $this->setError($msg); - $this->debug($msg); - return false; - } else { - $this->debug("parsing $xml"); - $this->parseString($xmlStr,$type); - $this->debug("done parsing $xml"); - return true; - } - } - return false; - } - - /** - * parse an XML string - * - * @param string $xml path or URL - * @param string $type, (schema|xml) - * @access private - */ - function parseString($xml,$type){ - // parse xml string - if($xml != ""){ - - // Create an XML parser. - $this->parser = xml_parser_create(); - // Set the options for parsing the XML data. - xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); - - // Set the object for the parser. - xml_set_object($this->parser, $this); - - // Set the element handlers for the parser. - if($type == "schema"){ - xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); - xml_set_character_data_handler($this->parser,'schemaCharacterData'); - } elseif($type == "xml"){ - xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); - xml_set_character_data_handler($this->parser,'xmlCharacterData'); - } - - // Parse the XML file. - if(!xml_parse($this->parser,$xml,true)){ - // Display an error message. - $errstr = sprintf('XML error parsing XML schema on line %d: %s', - xml_get_current_line_number($this->parser), - xml_error_string(xml_get_error_code($this->parser)) - ); - $this->debug($errstr); - $this->debug("XML payload:\n" . $xml); - $this->setError($errstr); - } - - xml_parser_free($this->parser); - } else{ - $this->debug('no xml passed to parseString()!!'); - $this->setError('no xml passed to parseString()!!'); - } - } - - /** - * start-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @param string $attrs associative array of attributes - * @access private - */ - function schemaStartElement($parser, $name, $attrs) { - - // position in the total number of elements, starting from 0 - $pos = $this->position++; - $depth = $this->depth++; - // set self as current value for this depth - $this->depth_array[$depth] = $pos; - $this->message[$pos] = array('cdata' => ''); - if ($depth > 0) { - $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; - } else { - $this->defaultNamespace[$pos] = false; - } - - // get element prefix - if($prefix = $this->getPrefix($name)){ - // get unqualified name - $name = $this->getLocalPart($name); - } else { - $prefix = ''; - } - - // loop thru attributes, expanding, and registering namespace declarations - if(count($attrs) > 0){ - foreach($attrs as $k => $v){ - // if ns declarations, add to class level array of valid namespaces - if(ereg("^xmlns",$k)){ - //$this->xdebug("$k: $v"); - //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); - if($ns_prefix = substr(strrchr($k,':'),1)){ - //$this->xdebug("Add namespace[$ns_prefix] = $v"); - $this->namespaces[$ns_prefix] = $v; - } else { - $this->defaultNamespace[$pos] = $v; - if (! $this->getPrefixFromNamespace($v)) { - $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; - } - } - if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ - $this->XMLSchemaVersion = $v; - $this->namespaces['xsi'] = $v.'-instance'; - } - } - } - foreach($attrs as $k => $v){ - // expand each attribute - $k = strpos($k,':') ? $this->expandQname($k) : $k; - $v = strpos($v,':') ? $this->expandQname($v) : $v; - $eAttrs[$k] = $v; - } - $attrs = $eAttrs; - } else { - $attrs = array(); - } - // find status, register data - switch($name){ - case 'all': // (optional) compositor content for a complexType - case 'choice': - case 'group': - case 'sequence': - //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); - $this->complexTypes[$this->currentComplexType]['compositor'] = $name; - //if($name == 'all' || $name == 'sequence'){ - // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; - //} - break; - case 'attribute': // complexType attribute - //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); - $this->xdebug("parsing attribute:"); - $this->appendDebug($this->varDump($attrs)); - if (!isset($attrs['form'])) { - $attrs['form'] = $this->schemaInfo['attributeFormDefault']; - } - if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { - $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - if (!strpos($v, ':')) { - // no namespace in arrayType attribute value... - if ($this->defaultNamespace[$pos]) { - // ...so use the default - $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - } - } - } - if(isset($attrs['name'])){ - $this->attributes[$attrs['name']] = $attrs; - $aname = $attrs['name']; - } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ - if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { - $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - } else { - $aname = ''; - } - } elseif(isset($attrs['ref'])){ - $aname = $attrs['ref']; - $this->attributes[$attrs['ref']] = $attrs; - } - - if($this->currentComplexType){ // This should *always* be - $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; - } - // arrayType attribute - if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - $prefix = $this->getPrefix($aname); - if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ - $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - } else { - $v = ''; - } - if(strpos($v,'[,]')){ - $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; - } - $v = substr($v,0,strpos($v,'[')); // clip the [] - if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ - $v = $this->XMLSchemaVersion.':'.$v; - } - $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; - } - break; - case 'complexContent': // (optional) content for a complexType - break; - case 'complexType': - array_push($this->complexTypeStack, $this->currentComplexType); - if(isset($attrs['name'])){ - $this->xdebug('processing named complexType '.$attrs['name']); - //$this->currentElement = false; - $this->currentComplexType = $attrs['name']; - $this->complexTypes[$this->currentComplexType] = $attrs; - $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; - // This is for constructs like - // <complexType name="ListOfString" base="soap:Array"> - // <sequence> - // <element name="string" type="xsd:string" - // minOccurs="0" maxOccurs="unbounded" /> - // </sequence> - // </complexType> - if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ - $this->xdebug('complexType is unusual array'); - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - } else { - $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; - } - }else{ - $this->xdebug('processing unnamed complexType for element '.$this->currentElement); - $this->currentComplexType = $this->currentElement . '_ContainedType'; - //$this->currentElement = false; - $this->complexTypes[$this->currentComplexType] = $attrs; - $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; - // This is for constructs like - // <complexType name="ListOfString" base="soap:Array"> - // <sequence> - // <element name="string" type="xsd:string" - // minOccurs="0" maxOccurs="unbounded" /> - // </sequence> - // </complexType> - if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ - $this->xdebug('complexType is unusual array'); - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - } else { - $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; - } - } - break; - case 'element': - array_push($this->elementStack, $this->currentElement); - // elements defined as part of a complex type should - // not really be added to $this->elements, but for some - // reason, they are - if (!isset($attrs['form'])) { - $attrs['form'] = $this->schemaInfo['elementFormDefault']; - } - if(isset($attrs['type'])){ - $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); - if (! $this->getPrefix($attrs['type'])) { - if ($this->defaultNamespace[$pos]) { - $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; - $this->xdebug('used default namespace to make type ' . $attrs['type']); - } - } - // This is for constructs like - // <complexType name="ListOfString" base="soap:Array"> - // <sequence> - // <element name="string" type="xsd:string" - // minOccurs="0" maxOccurs="unbounded" /> - // </sequence> - // </complexType> - if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { - $this->xdebug('arrayType for unusual array is ' . $attrs['type']); - $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; - } - $this->currentElement = $attrs['name']; - $this->elements[ $attrs['name'] ] = $attrs; - $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; - $ename = $attrs['name']; - } elseif(isset($attrs['ref'])){ - $this->xdebug("processing element as ref to ".$attrs['ref']); - $this->currentElement = "ref to ".$attrs['ref']; - $ename = $this->getLocalPart($attrs['ref']); - } else { - $this->xdebug("processing untyped element ".$attrs['name']); - $this->currentElement = $attrs['name']; - $this->elements[ $attrs['name'] ] = $attrs; - $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; - $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; - $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; - $ename = $attrs['name']; - } - if(isset($ename) && $this->currentComplexType){ - $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; - } - break; - case 'enumeration': // restriction value list member - $this->xdebug('enumeration ' . $attrs['value']); - if ($this->currentSimpleType) { - $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; - } elseif ($this->currentComplexType) { - $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; - } - break; - case 'extension': // simpleContent or complexContent type extension - $this->xdebug('extension ' . $attrs['base']); - if ($this->currentComplexType) { - $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; - } - break; - case 'import': - if (isset($attrs['schemaLocation'])) { - //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); - $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); - } else { - //$this->xdebug('import namespace ' . $attrs['namespace']); - $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); - if (! $this->getPrefixFromNamespace($attrs['namespace'])) { - $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; - } - } - break; - case 'list': // simpleType value list - break; - case 'restriction': // simpleType, simpleContent or complexContent value restriction - $this->xdebug('restriction ' . $attrs['base']); - if($this->currentSimpleType){ - $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; - } elseif($this->currentComplexType){ - $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; - if(strstr($attrs['base'],':') == ':Array'){ - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - } - } - break; - case 'schema': - $this->schemaInfo = $attrs; - $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); - if (isset($attrs['targetNamespace'])) { - $this->schemaTargetNamespace = $attrs['targetNamespace']; - } - if (!isset($attrs['elementFormDefault'])) { - $this->schemaInfo['elementFormDefault'] = 'unqualified'; - } - if (!isset($attrs['attributeFormDefault'])) { - $this->schemaInfo['attributeFormDefault'] = 'unqualified'; - } - break; - case 'simpleContent': // (optional) content for a complexType - break; - case 'simpleType': - array_push($this->simpleTypeStack, $this->currentSimpleType); - if(isset($attrs['name'])){ - $this->xdebug("processing simpleType for name " . $attrs['name']); - $this->currentSimpleType = $attrs['name']; - $this->simpleTypes[ $attrs['name'] ] = $attrs; - $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; - $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; - } else { - $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); - $this->currentSimpleType = $this->currentElement . '_ContainedType'; - //$this->currentElement = false; - $this->simpleTypes[$this->currentSimpleType] = $attrs; - $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; - } - break; - case 'union': // simpleType type list - break; - default: - //$this->xdebug("do not have anything to do for element $name"); - } - } - - /** - * end-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @access private - */ - function schemaEndElement($parser, $name) { - // bring depth down a notch - $this->depth--; - // position of current element is equal to the last value left in depth_array for my depth - if(isset($this->depth_array[$this->depth])){ - $pos = $this->depth_array[$this->depth]; - } - // get element prefix - if ($prefix = $this->getPrefix($name)){ - // get unqualified name - $name = $this->getLocalPart($name); - } else { - $prefix = ''; - } - // move on... - if($name == 'complexType'){ - $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); - $this->currentComplexType = array_pop($this->complexTypeStack); - //$this->currentElement = false; - } - if($name == 'element'){ - $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); - $this->currentElement = array_pop($this->elementStack); - } - if($name == 'simpleType'){ - $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); - $this->currentSimpleType = array_pop($this->simpleTypeStack); - } - } - - /** - * element content handler - * - * @param string $parser XML parser object - * @param string $data element content - * @access private - */ - function schemaCharacterData($parser, $data){ - $pos = $this->depth_array[$this->depth - 1]; - $this->message[$pos]['cdata'] .= $data; - } - - /** - * serialize the schema - * - * @access public - */ - function serializeSchema(){ - - $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); - $xml = ''; - // imports - if (sizeof($this->imports) > 0) { - foreach($this->imports as $ns => $list) { - foreach ($list as $ii) { - if ($ii['location'] != '') { - $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; - } else { - $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; - } - } - } - } - // complex types - foreach($this->complexTypes as $typeName => $attrs){ - $contentStr = ''; - // serialize child elements - if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ - foreach($attrs['elements'] as $element => $eParts){ - if(isset($eParts['ref'])){ - $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; - } else { - $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; - foreach ($eParts as $aName => $aValue) { - // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable - if ($aName != 'name' && $aName != 'type') { - $contentStr .= " $aName=\"$aValue\""; - } - } - $contentStr .= "/>\n"; - } - } - // compositor wraps elements - if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { - $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n"; - } - } - // attributes - if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ - foreach($attrs['attrs'] as $attr => $aParts){ - $contentStr .= " <$schemaPrefix:attribute"; - foreach ($aParts as $a => $v) { - if ($a == 'ref' || $a == 'type') { - $contentStr .= " $a=\"".$this->contractQName($v).'"'; - } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { - $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; - $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; - } else { - $contentStr .= " $a=\"$v\""; - } - } - $contentStr .= "/>\n"; - } - } - // if restriction - if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ - $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n"; - // complex or simple content - if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ - $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n"; - } - } - // finalize complex type - if($contentStr != ''){ - $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n"; - } else { - $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; - } - $xml .= $contentStr; - } - // simple types - if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ - foreach($this->simpleTypes as $typeName => $eParts){ - $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; - if (isset($eParts['enumeration'])) { - foreach ($eParts['enumeration'] as $e) { - $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; - } - } - $xml .= " </$schemaPrefix:simpleType>"; - } - } - // elements - if(isset($this->elements) && count($this->elements) > 0){ - foreach($this->elements as $element => $eParts){ - $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; - } - } - // attributes - if(isset($this->attributes) && count($this->attributes) > 0){ - foreach($this->attributes as $attr => $aParts){ - $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; - } - } - // finish 'er up - $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; - foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { - $el .= " xmlns:$nsp=\"$ns\"\n"; - } - $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n"; - return $xml; - } - - /** - * adds debug data to the clas level debug string - * - * @param string $string debug data - * @access private - */ - function xdebug($string){ - $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); - } - - /** - * get the PHP type of a user defined type in the schema - * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays - * returns false if no type exists, or not w/ the given namespace - * else returns a string that is either a native php type, or 'struct' - * - * @param string $type, name of defined type - * @param string $ns, namespace of type - * @return mixed - * @access public - * @deprecated - */ - function getPHPType($type,$ns){ - if(isset($this->typemap[$ns][$type])){ - //print "found type '$type' and ns $ns in typemap<br>"; - return $this->typemap[$ns][$type]; - } elseif(isset($this->complexTypes[$type])){ - //print "getting type '$type' and ns $ns from complexTypes array<br>"; - return $this->complexTypes[$type]['phpType']; - } - return false; - } - - /** - * returns an associative array of information about a given type - * returns false if no type exists by the given name - * - * For a complexType typeDef = array( - * 'restrictionBase' => '', - * 'phpType' => '', - * 'compositor' => '(sequence|all)', - * 'elements' => array(), // refs to elements array - * 'attrs' => array() // refs to attributes array - * ... and so on (see addComplexType) - * ) - * - * For simpleType or element, the array has different keys. - * - * @param string - * @return mixed - * @access public - * @see addComplexType - * @see addSimpleType - * @see addElement - */ - function getTypeDef($type){ - //$this->debug("in getTypeDef for type $type"); - if(isset($this->complexTypes[$type])){ - $this->xdebug("in getTypeDef, found complexType $type"); - return $this->complexTypes[$type]; - } elseif(isset($this->simpleTypes[$type])){ - $this->xdebug("in getTypeDef, found simpleType $type"); - if (!isset($this->simpleTypes[$type]['phpType'])) { - // get info for type to tack onto the simple type - // TODO: can this ever really apply (i.e. what is a simpleType really?) - $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); - $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); - $etype = $this->getTypeDef($uqType); - if ($etype) { - $this->xdebug("in getTypeDef, found type for simpleType $type:"); - $this->xdebug($this->varDump($etype)); - if (isset($etype['phpType'])) { - $this->simpleTypes[$type]['phpType'] = $etype['phpType']; - } - if (isset($etype['elements'])) { - $this->simpleTypes[$type]['elements'] = $etype['elements']; - } - } - } - return $this->simpleTypes[$type]; - } elseif(isset($this->elements[$type])){ - $this->xdebug("in getTypeDef, found element $type"); - if (!isset($this->elements[$type]['phpType'])) { - // get info for type to tack onto the element - $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); - $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); - $etype = $this->getTypeDef($uqType); - if ($etype) { - $this->xdebug("in getTypeDef, found type for element $type:"); - $this->xdebug($this->varDump($etype)); - if (isset($etype['phpType'])) { - $this->elements[$type]['phpType'] = $etype['phpType']; - } - if (isset($etype['elements'])) { - $this->elements[$type]['elements'] = $etype['elements']; - } - } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { - $this->xdebug("in getTypeDef, element $type is an XSD type"); - $this->elements[$type]['phpType'] = 'scalar'; - } - } - return $this->elements[$type]; - } elseif(isset($this->attributes[$type])){ - $this->xdebug("in getTypeDef, found attribute $type"); - return $this->attributes[$type]; - } elseif (ereg('_ContainedType$', $type)) { - $this->xdebug("in getTypeDef, have an untyped element $type"); - $typeDef['typeClass'] = 'simpleType'; - $typeDef['phpType'] = 'scalar'; - $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; - return $typeDef; - } - $this->xdebug("in getTypeDef, did not find $type"); - return false; - } - - /** - * returns a sample serialization of a given type, or false if no type by the given name - * - * @param string $type, name of type - * @return mixed - * @access public - * @deprecated - */ - function serializeTypeDef($type){ - //print "in sTD() for type $type<br>"; - if($typeDef = $this->getTypeDef($type)){ - $str .= '<'.$type; - if(is_array($typeDef['attrs'])){ - foreach($attrs as $attName => $data){ - $str .= " $attName=\"{type = ".$data['type']."}\""; - } - } - $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; - if(count($typeDef['elements']) > 0){ - $str .= ">"; - foreach($typeDef['elements'] as $element => $eData){ - $str .= $this->serializeTypeDef($element); - } - $str .= "</$type>"; - } elseif($typeDef['typeClass'] == 'element') { - $str .= "></$type>"; - } else { - $str .= "/>"; - } - return $str; - } - return false; - } - - /** - * returns HTML form elements that allow a user - * to enter values for creating an instance of the given type. - * - * @param string $name, name for type instance - * @param string $type, name of type - * @return string - * @access public - * @deprecated - */ - function typeToForm($name,$type){ - // get typedef - if($typeDef = $this->getTypeDef($type)){ - // if struct - if($typeDef['phpType'] == 'struct'){ - $buffer .= '<table>'; - foreach($typeDef['elements'] as $child => $childDef){ - $buffer .= " - <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td> - <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>"; - } - $buffer .= '</table>'; - // if array - } elseif($typeDef['phpType'] == 'array'){ - $buffer .= '<table>'; - for($i=0;$i < 3; $i++){ - $buffer .= " - <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> - <td><input type='text' name='parameters[".$name."][]'></td></tr>"; - } - $buffer .= '</table>'; - // if scalar - } else { - $buffer .= "<input type='text' name='parameters[$name]'>"; - } - } else { - $buffer .= "<input type='text' name='parameters[$name]'>"; - } - return $buffer; - } - - /** - * adds a complex type to the schema - * - * example: array - * - * addType( - * 'ArrayOfstring', - * 'complexType', - * 'array', - * '', - * 'SOAP-ENC:Array', - * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), - * 'xsd:string' - * ); - * - * example: PHP associative array ( SOAP Struct ) - * - * addType( - * 'SOAPStruct', - * 'complexType', - * 'struct', - * 'all', - * array('myVar'=> array('name'=>'myVar','type'=>'string') - * ); - * - * @param name - * @param typeClass (complexType|simpleType|attribute) - * @param phpType: currently supported are array and struct (php assoc array) - * @param compositor (all|sequence|choice) - * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param elements = array ( name = array(name=>'',type=>'') ) - * @param attrs = array( - * array( - * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", - * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" - * ) - * ) - * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) - * @access public - * @see getTypeDef - */ - function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ - $this->complexTypes[$name] = array( - 'name' => $name, - 'typeClass' => $typeClass, - 'phpType' => $phpType, - 'compositor'=> $compositor, - 'restrictionBase' => $restrictionBase, - 'elements' => $elements, - 'attrs' => $attrs, - 'arrayType' => $arrayType - ); - - $this->xdebug("addComplexType $name:"); - $this->appendDebug($this->varDump($this->complexTypes[$name])); - } - - /** - * adds a simple type to the schema - * - * @param string $name - * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param string $typeClass (should always be simpleType) - * @param string $phpType (should always be scalar) - * @param array $enumeration array of values - * @access public - * @see xmlschema - * @see getTypeDef - */ - function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { - $this->simpleTypes[$name] = array( - 'name' => $name, - 'typeClass' => $typeClass, - 'phpType' => $phpType, - 'type' => $restrictionBase, - 'enumeration' => $enumeration - ); - - $this->xdebug("addSimpleType $name:"); - $this->appendDebug($this->varDump($this->simpleTypes[$name])); - } - - /** - * adds an element to the schema - * - * @param array $attrs attributes that must include name and type - * @see xmlschema - * @access public - */ - function addElement($attrs) { - if (! $this->getPrefix($attrs['type'])) { - $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; - } - $this->elements[ $attrs['name'] ] = $attrs; - $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; - - $this->xdebug("addElement " . $attrs['name']); - $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); - } -} - - - - +<?php + + + + +/** +* parses an XML Schema, allows access to it's data, other utility methods +* no validation... yet. +* very experimental and limited. As is discussed on XML-DEV, I'm one of the people +* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty +* tutorials I refer to :) +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class XMLSchema extends nusoap_base { + + // files + var $schema = ''; + var $xml = ''; + // namespaces + var $enclosingNamespaces; + // schema info + var $schemaInfo = array(); + var $schemaTargetNamespace = ''; + // types, elements, attributes defined by the schema + var $attributes = array(); + var $complexTypes = array(); + var $complexTypeStack = array(); + var $currentComplexType = null; + var $elements = array(); + var $elementStack = array(); + var $currentElement = null; + var $simpleTypes = array(); + var $simpleTypeStack = array(); + var $currentSimpleType = null; + // imports + var $imports = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + var $message = array(); + var $defaultNamespace = array(); + + /** + * constructor + * + * @param string $schema schema document URI + * @param string $xml xml document URI + * @param string $namespaces namespaces defined in enclosing XML + * @access public + */ + function XMLSchema($schema='',$xml='',$namespaces=array()){ + parent::nusoap_base(); + $this->debug('xmlschema class instantiated, inside constructor'); + // files + $this->schema = $schema; + $this->xml = $xml; + + // namespaces + $this->enclosingNamespaces = $namespaces; + $this->namespaces = array_merge($this->namespaces, $namespaces); + + // parse schema file + if($schema != ''){ + $this->debug('initial schema file: '.$schema); + $this->parseFile($schema, 'schema'); + } + + // parse xml file + if($xml != ''){ + $this->debug('initial xml file: '.$xml); + $this->parseFile($xml, 'xml'); + } + + } + + /** + * parse an XML file + * + * @param string $xml, path/URL to XML file + * @param string $type, (schema | xml) + * @return boolean + * @access public + */ + function parseFile($xml,$type){ + // parse xml file + if($xml != ""){ + $xmlStr = @join("",@file($xml)); + if($xmlStr == ""){ + $msg = 'Error reading XML from '.$xml; + $this->setError($msg); + $this->debug($msg); + return false; + } else { + $this->debug("parsing $xml"); + $this->parseString($xmlStr,$type); + $this->debug("done parsing $xml"); + return true; + } + } + return false; + } + + /** + * parse an XML string + * + * @param string $xml path or URL + * @param string $type, (schema|xml) + * @access private + */ + function parseString($xml,$type){ + // parse xml string + if($xml != ""){ + + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + + // Set the object for the parser. + xml_set_object($this->parser, $this); + + // Set the element handlers for the parser. + if($type == "schema"){ + xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); + xml_set_character_data_handler($this->parser,'schemaCharacterData'); + } elseif($type == "xml"){ + xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); + xml_set_character_data_handler($this->parser,'xmlCharacterData'); + } + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $errstr = sprintf('XML error parsing XML schema on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $xml); + $this->setError($errstr); + } + + xml_parser_free($this->parser); + } else{ + $this->debug('no xml passed to parseString()!!'); + $this->setError('no xml passed to parseString()!!'); + } + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function schemaStartElement($parser, $name, $attrs) { + + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + if ($depth > 0) { + $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; + } else { + $this->defaultNamespace[$pos] = false; + } + + // get element prefix + if($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + + // loop thru attributes, expanding, and registering namespace declarations + if(count($attrs) > 0){ + foreach($attrs as $k => $v){ + // if ns declarations, add to class level array of valid namespaces + if(ereg("^xmlns",$k)){ + //$this->xdebug("$k: $v"); + //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); + if($ns_prefix = substr(strrchr($k,':'),1)){ + //$this->xdebug("Add namespace[$ns_prefix] = $v"); + $this->namespaces[$ns_prefix] = $v; + } else { + $this->defaultNamespace[$pos] = $v; + if (! $this->getPrefixFromNamespace($v)) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; + } + } + if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v.'-instance'; + } + } + } + foreach($attrs as $k => $v){ + // expand each attribute + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // find status, register data + switch($name){ + case 'all': // (optional) compositor content for a complexType + case 'choice': + case 'group': + case 'sequence': + //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); + $this->complexTypes[$this->currentComplexType]['compositor'] = $name; + //if($name == 'all' || $name == 'sequence'){ + // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + //} + break; + case 'attribute': // complexType attribute + //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); + $this->xdebug("parsing attribute:"); + $this->appendDebug($this->varDump($attrs)); + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['attributeFormDefault']; + } + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + if (!strpos($v, ':')) { + // no namespace in arrayType attribute value... + if ($this->defaultNamespace[$pos]) { + // ...so use the default + $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } + } + } + if(isset($attrs['name'])){ + $this->attributes[$attrs['name']] = $attrs; + $aname = $attrs['name']; + } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $aname = ''; + } + } elseif(isset($attrs['ref'])){ + $aname = $attrs['ref']; + $this->attributes[$attrs['ref']] = $attrs; + } + + if($this->currentComplexType){ // This should *always* be + $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; + } + // arrayType attribute + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + $prefix = $this->getPrefix($aname); + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $v = ''; + } + if(strpos($v,'[,]')){ + $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; + } + $v = substr($v,0,strpos($v,'[')); // clip the [] + if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ + $v = $this->XMLSchemaVersion.':'.$v; + } + $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; + } + break; + case 'complexContent': // (optional) content for a complexType + break; + case 'complexType': + array_push($this->complexTypeStack, $this->currentComplexType); + if(isset($attrs['name'])){ + $this->xdebug('processing named complexType '.$attrs['name']); + //$this->currentElement = false; + $this->currentComplexType = $attrs['name']; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // <complexType name="ListOfString" base="soap:Array"> + // <sequence> + // <element name="string" type="xsd:string" + // minOccurs="0" maxOccurs="unbounded" /> + // </sequence> + // </complexType> + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + }else{ + $this->xdebug('processing unnamed complexType for element '.$this->currentElement); + $this->currentComplexType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // <complexType name="ListOfString" base="soap:Array"> + // <sequence> + // <element name="string" type="xsd:string" + // minOccurs="0" maxOccurs="unbounded" /> + // </sequence> + // </complexType> + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + } + break; + case 'element': + array_push($this->elementStack, $this->currentElement); + // elements defined as part of a complex type should + // not really be added to $this->elements, but for some + // reason, they are + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['elementFormDefault']; + } + if(isset($attrs['type'])){ + $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); + if (! $this->getPrefix($attrs['type'])) { + if ($this->defaultNamespace[$pos]) { + $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; + $this->xdebug('used default namespace to make type ' . $attrs['type']); + } + } + // This is for constructs like + // <complexType name="ListOfString" base="soap:Array"> + // <sequence> + // <element name="string" type="xsd:string" + // minOccurs="0" maxOccurs="unbounded" /> + // </sequence> + // </complexType> + if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { + $this->xdebug('arrayType for unusual array is ' . $attrs['type']); + $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; + } + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $ename = $attrs['name']; + } elseif(isset($attrs['ref'])){ + $this->xdebug("processing element as ref to ".$attrs['ref']); + $this->currentElement = "ref to ".$attrs['ref']; + $ename = $this->getLocalPart($attrs['ref']); + } else { + $this->xdebug("processing untyped element ".$attrs['name']); + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; + $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; + $ename = $attrs['name']; + } + if(isset($ename) && $this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; + } + break; + case 'enumeration': // restriction value list member + $this->xdebug('enumeration ' . $attrs['value']); + if ($this->currentSimpleType) { + $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; + } elseif ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; + } + break; + case 'extension': // simpleContent or complexContent type extension + $this->xdebug('extension ' . $attrs['base']); + if ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; + } + break; + case 'import': + if (isset($attrs['schemaLocation'])) { + //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); + $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); + } else { + //$this->xdebug('import namespace ' . $attrs['namespace']); + $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + } + break; + case 'list': // simpleType value list + break; + case 'restriction': // simpleType, simpleContent or complexContent value restriction + $this->xdebug('restriction ' . $attrs['base']); + if($this->currentSimpleType){ + $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; + } elseif($this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; + if(strstr($attrs['base'],':') == ':Array'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } + } + break; + case 'schema': + $this->schemaInfo = $attrs; + $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); + if (isset($attrs['targetNamespace'])) { + $this->schemaTargetNamespace = $attrs['targetNamespace']; + } + if (!isset($attrs['elementFormDefault'])) { + $this->schemaInfo['elementFormDefault'] = 'unqualified'; + } + if (!isset($attrs['attributeFormDefault'])) { + $this->schemaInfo['attributeFormDefault'] = 'unqualified'; + } + break; + case 'simpleContent': // (optional) content for a complexType + break; + case 'simpleType': + array_push($this->simpleTypeStack, $this->currentSimpleType); + if(isset($attrs['name'])){ + $this->xdebug("processing simpleType for name " . $attrs['name']); + $this->currentSimpleType = $attrs['name']; + $this->simpleTypes[ $attrs['name'] ] = $attrs; + $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; + $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; + } else { + $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); + $this->currentSimpleType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->simpleTypes[$this->currentSimpleType] = $attrs; + $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; + } + break; + case 'union': // simpleType type list + break; + default: + //$this->xdebug("do not have anything to do for element $name"); + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function schemaEndElement($parser, $name) { + // bring depth down a notch + $this->depth--; + // position of current element is equal to the last value left in depth_array for my depth + if(isset($this->depth_array[$this->depth])){ + $pos = $this->depth_array[$this->depth]; + } + // get element prefix + if ($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + // move on... + if($name == 'complexType'){ + $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); + $this->currentComplexType = array_pop($this->complexTypeStack); + //$this->currentElement = false; + } + if($name == 'element'){ + $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); + $this->currentElement = array_pop($this->elementStack); + } + if($name == 'simpleType'){ + $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); + $this->currentSimpleType = array_pop($this->simpleTypeStack); + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function schemaCharacterData($parser, $data){ + $pos = $this->depth_array[$this->depth - 1]; + $this->message[$pos]['cdata'] .= $data; + } + + /** + * serialize the schema + * + * @access public + */ + function serializeSchema(){ + + $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); + $xml = ''; + // imports + if (sizeof($this->imports) > 0) { + foreach($this->imports as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; + } else { + $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; + } + } + } + } + // complex types + foreach($this->complexTypes as $typeName => $attrs){ + $contentStr = ''; + // serialize child elements + if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ + foreach($attrs['elements'] as $element => $eParts){ + if(isset($eParts['ref'])){ + $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; + } else { + $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; + foreach ($eParts as $aName => $aValue) { + // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable + if ($aName != 'name' && $aName != 'type') { + $contentStr .= " $aName=\"$aValue\""; + } + } + $contentStr .= "/>\n"; + } + } + // compositor wraps elements + if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { + $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n"; + } + } + // attributes + if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ + foreach($attrs['attrs'] as $attr => $aParts){ + $contentStr .= " <$schemaPrefix:attribute"; + foreach ($aParts as $a => $v) { + if ($a == 'ref' || $a == 'type') { + $contentStr .= " $a=\"".$this->contractQName($v).'"'; + } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { + $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; + $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; + } else { + $contentStr .= " $a=\"$v\""; + } + } + $contentStr .= "/>\n"; + } + } + // if restriction + if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ + $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n"; + // complex or simple content + if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ + $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n"; + } + } + // finalize complex type + if($contentStr != ''){ + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n"; + } else { + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; + } + $xml .= $contentStr; + } + // simple types + if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ + foreach($this->simpleTypes as $typeName => $eParts){ + $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; + if (isset($eParts['enumeration'])) { + foreach ($eParts['enumeration'] as $e) { + $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; + } + } + $xml .= " </$schemaPrefix:simpleType>"; + } + } + // elements + if(isset($this->elements) && count($this->elements) > 0){ + foreach($this->elements as $element => $eParts){ + $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; + } + } + // attributes + if(isset($this->attributes) && count($this->attributes) > 0){ + foreach($this->attributes as $attr => $aParts){ + $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; + } + } + // finish 'er up + $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; + foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { + $el .= " xmlns:$nsp=\"$ns\"\n"; + } + $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n"; + return $xml; + } + + /** + * adds debug data to the clas level debug string + * + * @param string $string debug data + * @access private + */ + function xdebug($string){ + $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); + } + + /** + * get the PHP type of a user defined type in the schema + * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays + * returns false if no type exists, or not w/ the given namespace + * else returns a string that is either a native php type, or 'struct' + * + * @param string $type, name of defined type + * @param string $ns, namespace of type + * @return mixed + * @access public + * @deprecated + */ + function getPHPType($type,$ns){ + if(isset($this->typemap[$ns][$type])){ + //print "found type '$type' and ns $ns in typemap<br>"; + return $this->typemap[$ns][$type]; + } elseif(isset($this->complexTypes[$type])){ + //print "getting type '$type' and ns $ns from complexTypes array<br>"; + return $this->complexTypes[$type]['phpType']; + } + return false; + } + + /** + * returns an associative array of information about a given type + * returns false if no type exists by the given name + * + * For a complexType typeDef = array( + * 'restrictionBase' => '', + * 'phpType' => '', + * 'compositor' => '(sequence|all)', + * 'elements' => array(), // refs to elements array + * 'attrs' => array() // refs to attributes array + * ... and so on (see addComplexType) + * ) + * + * For simpleType or element, the array has different keys. + * + * @param string + * @return mixed + * @access public + * @see addComplexType + * @see addSimpleType + * @see addElement + */ + function getTypeDef($type){ + //$this->debug("in getTypeDef for type $type"); + if(isset($this->complexTypes[$type])){ + $this->xdebug("in getTypeDef, found complexType $type"); + return $this->complexTypes[$type]; + } elseif(isset($this->simpleTypes[$type])){ + $this->xdebug("in getTypeDef, found simpleType $type"); + if (!isset($this->simpleTypes[$type]['phpType'])) { + // get info for type to tack onto the simple type + // TODO: can this ever really apply (i.e. what is a simpleType really?) + $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); + $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for simpleType $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->simpleTypes[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->simpleTypes[$type]['elements'] = $etype['elements']; + } + } + } + return $this->simpleTypes[$type]; + } elseif(isset($this->elements[$type])){ + $this->xdebug("in getTypeDef, found element $type"); + if (!isset($this->elements[$type]['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); + $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for element $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->elements[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->elements[$type]['elements'] = $etype['elements']; + } + } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { + $this->xdebug("in getTypeDef, element $type is an XSD type"); + $this->elements[$type]['phpType'] = 'scalar'; + } + } + return $this->elements[$type]; + } elseif(isset($this->attributes[$type])){ + $this->xdebug("in getTypeDef, found attribute $type"); + return $this->attributes[$type]; + } elseif (ereg('_ContainedType$', $type)) { + $this->xdebug("in getTypeDef, have an untyped element $type"); + $typeDef['typeClass'] = 'simpleType'; + $typeDef['phpType'] = 'scalar'; + $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; + return $typeDef; + } + $this->xdebug("in getTypeDef, did not find $type"); + return false; + } + + /** + * returns a sample serialization of a given type, or false if no type by the given name + * + * @param string $type, name of type + * @return mixed + * @access public + * @deprecated + */ + function serializeTypeDef($type){ + //print "in sTD() for type $type<br>"; + if($typeDef = $this->getTypeDef($type)){ + $str .= '<'.$type; + if(is_array($typeDef['attrs'])){ + foreach($attrs as $attName => $data){ + $str .= " $attName=\"{type = ".$data['type']."}\""; + } + } + $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; + if(count($typeDef['elements']) > 0){ + $str .= ">"; + foreach($typeDef['elements'] as $element => $eData){ + $str .= $this->serializeTypeDef($element); + } + $str .= "</$type>"; + } elseif($typeDef['typeClass'] == 'element') { + $str .= "></$type>"; + } else { + $str .= "/>"; + } + return $str; + } + return false; + } + + /** + * returns HTML form elements that allow a user + * to enter values for creating an instance of the given type. + * + * @param string $name, name for type instance + * @param string $type, name of type + * @return string + * @access public + * @deprecated + */ + function typeToForm($name,$type){ + // get typedef + if($typeDef = $this->getTypeDef($type)){ + // if struct + if($typeDef['phpType'] == 'struct'){ + $buffer .= '<table>'; + foreach($typeDef['elements'] as $child => $childDef){ + $buffer .= " + <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td> + <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>"; + } + $buffer .= '</table>'; + // if array + } elseif($typeDef['phpType'] == 'array'){ + $buffer .= '<table>'; + for($i=0;$i < 3; $i++){ + $buffer .= " + <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> + <td><input type='text' name='parameters[".$name."][]'></td></tr>"; + } + $buffer .= '</table>'; + // if scalar + } else { + $buffer .= "<input type='text' name='parameters[$name]'>"; + } + } else { + $buffer .= "<input type='text' name='parameters[$name]'>"; + } + return $buffer; + } + + /** + * adds a complex type to the schema + * + * example: array + * + * addType( + * 'ArrayOfstring', + * 'complexType', + * 'array', + * '', + * 'SOAP-ENC:Array', + * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), + * 'xsd:string' + * ); + * + * example: PHP associative array ( SOAP Struct ) + * + * addType( + * 'SOAPStruct', + * 'complexType', + * 'struct', + * 'all', + * array('myVar'=> array('name'=>'myVar','type'=>'string') + * ); + * + * @param name + * @param typeClass (complexType|simpleType|attribute) + * @param phpType: currently supported are array and struct (php assoc array) + * @param compositor (all|sequence|choice) + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param elements = array ( name = array(name=>'',type=>'') ) + * @param attrs = array( + * array( + * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", + * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" + * ) + * ) + * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) + * @access public + * @see getTypeDef + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ + $this->complexTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'compositor'=> $compositor, + 'restrictionBase' => $restrictionBase, + 'elements' => $elements, + 'attrs' => $attrs, + 'arrayType' => $arrayType + ); + + $this->xdebug("addComplexType $name:"); + $this->appendDebug($this->varDump($this->complexTypes[$name])); + } + + /** + * adds a simple type to the schema + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @access public + * @see xmlschema + * @see getTypeDef + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $this->simpleTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'type' => $restrictionBase, + 'enumeration' => $enumeration + ); + + $this->xdebug("addSimpleType $name:"); + $this->appendDebug($this->varDump($this->simpleTypes[$name])); + } + + /** + * adds an element to the schema + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + if (! $this->getPrefix($attrs['type'])) { + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; + } + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + + $this->xdebug("addElement " . $attrs['name']); + $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); + } +} + + + + ?> \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/nusoap.php b/htdocs/includes/nusoap/lib/nusoap.php index fdf83948857a2434ee40db0b89933a37125ec5f7..dfb13d065d1c48b666d552baac521acb8223b0df 100644 --- a/htdocs/includes/nusoap/lib/nusoap.php +++ b/htdocs/includes/nusoap/lib/nusoap.php @@ -1,7241 +1,7241 @@ -<?php - -/* -$Id$ - -NuSOAP - Web Services Toolkit for PHP - -Copyright (c) 2002 NuSphere Corporation - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -If you have any questions or comments, please email: - -Dietrich Ayala -dietrich@ganx4.com -http://dietrich.ganx4.com/nusoap - -NuSphere Corporation -http://www.nusphere.com - -*/ - -/* load classes - -// necessary classes -require_once('class.soapclient.php'); -require_once('class.soap_val.php'); -require_once('class.soap_parser.php'); -require_once('class.soap_fault.php'); - -// transport classes -require_once('class.soap_transport_http.php'); - -// optional add-on classes -require_once('class.xmlschema.php'); -require_once('class.wsdl.php'); - -// server class -require_once('class.soap_server.php');*/ - -// class variable emulation -// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html -$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; - -/** -* -* nusoap_base -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class nusoap_base { - /** - * Identification for HTTP headers. - * - * @var string - * @access private - */ - var $title = 'NuSOAP'; - /** - * Version for HTTP headers. - * - * @var string - * @access private - */ - var $version = '0.7.2'; - /** - * CVS revision for HTTP headers. - * - * @var string - * @access private - */ - var $revision = '$Revision$'; - /** - * Current error string (manipulated by getError/setError) - * - * @var string - * @access private - */ - var $error_str = ''; - /** - * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) - * - * @var string - * @access private - */ - var $debug_str = ''; - /** - * toggles automatic encoding of special characters as entities - * (should always be true, I think) - * - * @var boolean - * @access private - */ - var $charencoding = true; - /** - * the debug level for this instance - * - * @var integer - * @access private - */ - var $debugLevel; - - /** - * set schema version - * - * @var string - * @access public - */ - var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; - - /** - * charset encoding for outgoing messages - * - * @var string - * @access public - */ - var $soap_defencoding = 'ISO-8859-1'; - //var $soap_defencoding = 'UTF-8'; - - /** - * namespaces in an array of prefix => uri - * - * this is "seeded" by a set of constants, but it may be altered by code - * - * @var array - * @access public - */ - var $namespaces = array( - 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', - 'xsd' => 'http://www.w3.org/2001/XMLSchema', - 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' - ); - - /** - * namespaces used in the current context, e.g. during serialization - * - * @var array - * @access private - */ - var $usedNamespaces = array(); - - /** - * XML Schema types in an array of uri => (array of xml type => php type) - * is this legacy yet? - * no, this is used by the xmlschema class to verify type => namespace mappings. - * @var array - * @access public - */ - var $typemap = array( - 'http://www.w3.org/2001/XMLSchema' => array( - 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', - 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', - 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', - // abstract "any" types - 'anyType'=>'string','anySimpleType'=>'string', - // derived datatypes - 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', - 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', - 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', - 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), - 'http://www.w3.org/2000/10/XMLSchema' => array( - 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', - 'float'=>'double','dateTime'=>'string', - 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), - 'http://www.w3.org/1999/XMLSchema' => array( - 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', - 'float'=>'double','dateTime'=>'string', - 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), - 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), - 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), - 'http://xml.apache.org/xml-soap' => array('Map') - ); - - /** - * XML entities to convert - * - * @var array - * @access public - * @deprecated - * @see expandEntities - */ - var $xmlEntities = array('quot' => '"','amp' => '&', - 'lt' => '<','gt' => '>','apos' => "'"); - - /** - * constructor - * - * @access public - */ - function nusoap_base() { - $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; - } - - /** - * gets the global debug level, which applies to future instances - * - * @return integer Debug level 0-9, where 0 turns off - * @access public - */ - function getGlobalDebugLevel() { - return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; - } - - /** - * sets the global debug level, which applies to future instances - * - * @param int $level Debug level 0-9, where 0 turns off - * @access public - */ - function setGlobalDebugLevel($level) { - $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; - } - - /** - * gets the debug level for this instance - * - * @return int Debug level 0-9, where 0 turns off - * @access public - */ - function getDebugLevel() { - return $this->debugLevel; - } - - /** - * sets the debug level for this instance - * - * @param int $level Debug level 0-9, where 0 turns off - * @access public - */ - function setDebugLevel($level) { - $this->debugLevel = $level; - } - - /** - * adds debug data to the instance debug string with formatting - * - * @param string $string debug data - * @access private - */ - function debug($string){ - if ($this->debugLevel > 0) { - $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); - } - } - - /** - * adds debug data to the instance debug string without formatting - * - * @param string $string debug data - * @access public - */ - function appendDebug($string){ - if ($this->debugLevel > 0) { - // it would be nice to use a memory stream here to use - // memory more efficiently - $this->debug_str .= $string; - } - } - - /** - * clears the current debug data for this instance - * - * @access public - */ - function clearDebug() { - // it would be nice to use a memory stream here to use - // memory more efficiently - $this->debug_str = ''; - } - - /** - * gets the current debug data for this instance - * - * @return debug data - * @access public - */ - function &getDebug() { - // it would be nice to use a memory stream here to use - // memory more efficiently - return $this->debug_str; - } - - /** - * gets the current debug data for this instance as an XML comment - * this may change the contents of the debug data - * - * @return debug data as an XML comment - * @access public - */ - function &getDebugAsXMLComment() { - // it would be nice to use a memory stream here to use - // memory more efficiently - while (strpos($this->debug_str, '--')) { - $this->debug_str = str_replace('--', '- -', $this->debug_str); - } - return "<!--\n" . $this->debug_str . "\n-->"; - } - - /** - * expands entities, e.g. changes '<' to '<'. - * - * @param string $val The string in which to expand entities. - * @access private - */ - function expandEntities($val) { - if ($this->charencoding) { - $val = str_replace('&', '&', $val); - $val = str_replace("'", ''', $val); - $val = str_replace('"', '"', $val); - $val = str_replace('<', '<', $val); - $val = str_replace('>', '>', $val); - } - return $val; - } - - /** - * returns error string if present - * - * @return mixed error string or false - * @access public - */ - function getError(){ - if($this->error_str != ''){ - return $this->error_str; - } - return false; - } - - /** - * sets error string - * - * @return boolean $string error string - * @access private - */ - function setError($str){ - $this->error_str = $str; - } - - /** - * detect if array is a simple array or a struct (associative array) - * - * @param mixed $val The PHP array - * @return string (arraySimple|arrayStruct) - * @access private - */ - function isArraySimpleOrStruct($val) { - $keyList = array_keys($val); - foreach ($keyList as $keyListValue) { - if (!is_int($keyListValue)) { - return 'arrayStruct'; - } - } - return 'arraySimple'; - } - - /** - * serializes PHP values in accordance w/ section 5. Type information is - * not serialized if $use == 'literal'. - * - * @param mixed $val The value to serialize - * @param string $name The name (local part) of the XML element - * @param string $type The XML schema type (local part) for the element - * @param string $name_ns The namespace for the name of the XML element - * @param string $type_ns The namespace for the type of the element - * @param array $attributes The attributes to serialize as name=>value pairs - * @param string $use The WSDL "use" (encoded|literal) - * @return string The serialized element, possibly with child elements - * @access public - */ - function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ - $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); - $this->appendDebug('value=' . $this->varDump($val)); - $this->appendDebug('attributes=' . $this->varDump($attributes)); - - if(is_object($val) && get_class($val) == 'soapval'){ - return $val->serialize($use); - } - // force valid name if necessary - if (is_numeric($name)) { - $name = '__numeric_' . $name; - } elseif (! $name) { - $name = 'noname'; - } - // if name has ns, add ns prefix to name - $xmlns = ''; - if($name_ns){ - $prefix = 'nu'.rand(1000,9999); - $name = $prefix.':'.$name; - $xmlns .= " xmlns:$prefix=\"$name_ns\""; - } - // if type is prefixed, create type prefix - if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ - // need to fix this. shouldn't default to xsd if no ns specified - // w/o checking against typemap - $type_prefix = 'xsd'; - } elseif($type_ns){ - $type_prefix = 'ns'.rand(1000,9999); - $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; - } - // serialize attributes if present - $atts = ''; - if($attributes){ - foreach($attributes as $k => $v){ - $atts .= " $k=\"".$this->expandEntities($v).'"'; - } - } - // serialize null value - if (is_null($val)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - return "<$name$xmlns $atts/>"; - } else { - if (isset($type) && isset($type_prefix)) { - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = ''; - } - return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; - } - } - // serialize if an xsd built-in primitive type - if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ - if (is_bool($val)) { - if ($type == 'boolean') { - $val = $val ? 'true' : 'false'; - } elseif (! $val) { - $val = 0; - } - } else if (is_string($val)) { - $val = $this->expandEntities($val); - } - if ($use == 'literal') { - return "<$name$xmlns $atts>$val</$name>"; - } else { - return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>"; - } - } - // detect type and serialize - $xml = ''; - switch(true) { - case (is_bool($val) || $type == 'boolean'): - if ($type == 'boolean') { - $val = $val ? 'true' : 'false'; - } elseif (! $val) { - $val = 0; - } - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>"; - } - break; - case (is_int($val) || is_long($val) || $type == 'int'): - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>"; - } - break; - case (is_float($val)|| is_double($val) || $type == 'float'): - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>"; - } - break; - case (is_string($val) || $type == 'string'): - $val = $this->expandEntities($val); - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>$val</$name>"; - } else { - $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>"; - } - break; - case is_object($val): - if (! $name) { - $name = get_class($val); - $this->debug("In serialize_val, used class name $name as element name"); - } else { - $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); - } - foreach(get_object_vars($val) as $k => $v){ - $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); - } - $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>'; - break; - break; - case (is_array($val) || $type): - // detect if struct or array - $valueType = $this->isArraySimpleOrStruct($val); - if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ - $i = 0; - if(is_array($val) && count($val)> 0){ - foreach($val as $v){ - if(is_object($v) && get_class($v) == 'soapval'){ - $tt_ns = $v->type_ns; - $tt = $v->type; - } elseif (is_array($v)) { - $tt = $this->isArraySimpleOrStruct($v); - } else { - $tt = gettype($v); - } - $array_types[$tt] = 1; - // TODO: for literal, the name should be $name - $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); - ++$i; - } - if(count($array_types) > 1){ - $array_typename = 'xsd:anyType'; - } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { - if ($tt == 'integer') { - $tt = 'int'; - } - $array_typename = 'xsd:'.$tt; - } elseif(isset($tt) && $tt == 'arraySimple'){ - $array_typename = 'SOAP-ENC:Array'; - } elseif(isset($tt) && $tt == 'arrayStruct'){ - $array_typename = 'unnamed_struct_use_soapval'; - } else { - // if type is prefixed, create type prefix - if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ - $array_typename = 'xsd:' . $tt; - } elseif ($tt_ns) { - $tt_prefix = 'ns' . rand(1000, 9999); - $array_typename = "$tt_prefix:$tt"; - $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; - } else { - $array_typename = $tt; - } - } - $array_type = $i; - if ($use == 'literal') { - $type_str = ''; - } else if (isset($type) && isset($type_prefix)) { - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; - } - // empty array - } else { - if ($use == 'literal') { - $type_str = ''; - } else if (isset($type) && isset($type_prefix)) { - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; - } - } - // TODO: for array in literal, there is no wrapper here - $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>"; - } else { - // got a struct - if(isset($type) && isset($type_prefix)){ - $type_str = " xsi:type=\"$type_prefix:$type\""; - } else { - $type_str = ''; - } - if ($use == 'literal') { - $xml .= "<$name$xmlns $atts>"; - } else { - $xml .= "<$name$xmlns$type_str$atts>"; - } - foreach($val as $k => $v){ - // Apache Map - if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { - $xml .= '<item>'; - $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); - $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); - $xml .= '</item>'; - } else { - $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); - } - } - $xml .= "</$name>"; - } - break; - default: - $xml .= 'not detected, got '.gettype($val).' for '.$val; - break; - } - return $xml; - } - - /** - * serializes a message - * - * @param string $body the XML of the SOAP body - * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers - * @param array $namespaces optional the namespaces used in generating the body and headers - * @param string $style optional (rpc|document) - * @param string $use optional (encoded|literal) - * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) - * @return string the message - * @access public - */ - function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ - // TODO: add an option to automatically run utf8_encode on $body and $headers - // if $this->soap_defencoding is UTF-8. Not doing this automatically allows - // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 - - $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); - $this->debug("headers:"); - $this->appendDebug($this->varDump($headers)); - $this->debug("namespaces:"); - $this->appendDebug($this->varDump($namespaces)); - - // serialize namespaces - $ns_string = ''; - foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ - $ns_string .= " xmlns:$k=\"$v\""; - } - if($encodingStyle) { - $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; - } - - // serialize headers - if($headers){ - if (is_array($headers)) { - $xml = ''; - foreach ($headers as $header) { - $xml .= $this->serialize_val($header, false, false, false, false, false, $use); - } - $headers = $xml; - $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); - } - $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>"; - } - // serialize envelope - return - '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">". - '<SOAP-ENV:Envelope'.$ns_string.">". - $headers. - "<SOAP-ENV:Body>". - $body. - "</SOAP-ENV:Body>". - "</SOAP-ENV:Envelope>"; - } - - /** - * formats a string to be inserted into an HTML stream - * - * @param string $str The string to format - * @return string The formatted string - * @access public - * @deprecated - */ - function formatDump($str){ - $str = htmlspecialchars($str); - return nl2br($str); - } - - /** - * contracts (changes namespace to prefix) a qualified name - * - * @param string $qname qname - * @return string contracted qname - * @access private - */ - function contractQname($qname){ - // get element namespace - //$this->xdebug("Contract $qname"); - if (strrpos($qname, ':')) { - // get unqualified name - $name = substr($qname, strrpos($qname, ':') + 1); - // get ns - $ns = substr($qname, 0, strrpos($qname, ':')); - $p = $this->getPrefixFromNamespace($ns); - if ($p) { - return $p . ':' . $name; - } - return $qname; - } else { - return $qname; - } - } - - /** - * expands (changes prefix to namespace) a qualified name - * - * @param string $string qname - * @return string expanded qname - * @access private - */ - function expandQname($qname){ - // get element prefix - if(strpos($qname,':') && !ereg('^http://',$qname)){ - // get unqualified name - $name = substr(strstr($qname,':'),1); - // get ns prefix - $prefix = substr($qname,0,strpos($qname,':')); - if(isset($this->namespaces[$prefix])){ - return $this->namespaces[$prefix].':'.$name; - } else { - return $qname; - } - } else { - return $qname; - } - } - - /** - * returns the local part of a prefixed string - * returns the original string, if not prefixed - * - * @param string $str The prefixed string - * @return string The local part - * @access public - */ - function getLocalPart($str){ - if($sstr = strrchr($str,':')){ - // get unqualified name - return substr( $sstr, 1 ); - } else { - return $str; - } - } - - /** - * returns the prefix part of a prefixed string - * returns false, if not prefixed - * - * @param string $str The prefixed string - * @return mixed The prefix or false if there is no prefix - * @access public - */ - function getPrefix($str){ - if($pos = strrpos($str,':')){ - // get prefix - return substr($str,0,$pos); - } - return false; - } - - /** - * pass it a prefix, it returns a namespace - * - * @param string $prefix The prefix - * @return mixed The namespace, false if no namespace has the specified prefix - * @access public - */ - function getNamespaceFromPrefix($prefix){ - if (isset($this->namespaces[$prefix])) { - return $this->namespaces[$prefix]; - } - //$this->setError("No namespace registered for prefix '$prefix'"); - return false; - } - - /** - * returns the prefix for a given namespace (or prefix) - * or false if no prefixes registered for the given namespace - * - * @param string $ns The namespace - * @return mixed The prefix, false if the namespace has no prefixes - * @access public - */ - function getPrefixFromNamespace($ns) { - foreach ($this->namespaces as $p => $n) { - if ($ns == $n || $ns == $p) { - $this->usedNamespaces[$p] = $n; - return $p; - } - } - return false; - } - - /** - * returns the time in ODBC canonical form with microseconds - * - * @return string The time in ODBC canonical form with microseconds - * @access public - */ - function getmicrotime() { - if (function_exists('gettimeofday')) { - $tod = gettimeofday(); - $sec = $tod['sec']; - $usec = $tod['usec']; - } else { - $sec = time(); - $usec = 0; - } - return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); - } - - /** - * Returns a string with the output of var_dump - * - * @param mixed $data The variable to var_dump - * @return string The output of var_dump - * @access public - */ - function varDump($data) { - ob_start(); - var_dump($data); - $ret_val = ob_get_contents(); - ob_end_clean(); - return $ret_val; - } -} - -// XML Schema Datatype Helper Functions - -//xsd:dateTime helpers - -/** -* convert unix timestamp to ISO 8601 compliant date string -* -* @param string $timestamp Unix time stamp -* @access public -*/ -function timestamp_to_iso8601($timestamp,$utc=true){ - $datestr = date('Y-m-d\TH:i:sO',$timestamp); - if($utc){ - $eregStr = - '([0-9]{4})-'. // centuries & years CCYY- - '([0-9]{2})-'. // months MM- - '([0-9]{2})'. // days DD - 'T'. // separator T - '([0-9]{2}):'. // hours hh: - '([0-9]{2}):'. // minutes mm: - '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... - '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's - - if(ereg($eregStr,$datestr,$regs)){ - return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); - } - return false; - } else { - return $datestr; - } -} - -/** -* convert ISO 8601 compliant date string to unix timestamp -* -* @param string $datestr ISO 8601 compliant date string -* @access public -*/ -function iso8601_to_timestamp($datestr){ - $eregStr = - '([0-9]{4})-'. // centuries & years CCYY- - '([0-9]{2})-'. // months MM- - '([0-9]{2})'. // days DD - 'T'. // separator T - '([0-9]{2}):'. // hours hh: - '([0-9]{2}):'. // minutes mm: - '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... - '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's - if(ereg($eregStr,$datestr,$regs)){ - // not utc - if($regs[8] != 'Z'){ - $op = substr($regs[8],0,1); - $h = substr($regs[8],1,2); - $m = substr($regs[8],strlen($regs[8])-2,2); - if($op == '-'){ - $regs[4] = $regs[4] + $h; - $regs[5] = $regs[5] + $m; - } elseif($op == '+'){ - $regs[4] = $regs[4] - $h; - $regs[5] = $regs[5] - $m; - } - } - return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); - } else { - return false; - } -} - -/** -* sleeps some number of microseconds -* -* @param string $usec the number of microseconds to sleep -* @access public -* @deprecated -*/ -function usleepWindows($usec) -{ - $start = gettimeofday(); - - do - { - $stop = gettimeofday(); - $timePassed = 1000000 * ($stop['sec'] - $start['sec']) - + $stop['usec'] - $start['usec']; - } - while ($timePassed < $usec); -} - -?><?php - - - -/** -* Contains information for a SOAP fault. -* Mainly used for returning faults from deployed functions -* in a server instance. -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_fault extends nusoap_base { - /** - * The fault code (client|server) - * @var string - * @access private - */ - var $faultcode; - /** - * The fault actor - * @var string - * @access private - */ - var $faultactor; - /** - * The fault string, a description of the fault - * @var string - * @access private - */ - var $faultstring; - /** - * The fault detail, typically a string or array of string - * @var mixed - * @access private - */ - var $faultdetail; - - /** - * constructor - * - * @param string $faultcode (client | server) - * @param string $faultactor only used when msg routed between multiple actors - * @param string $faultstring human readable error message - * @param mixed $faultdetail detail, typically a string or array of string - */ - function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ - parent::nusoap_base(); - $this->faultcode = $faultcode; - $this->faultactor = $faultactor; - $this->faultstring = $faultstring; - $this->faultdetail = $faultdetail; - } - - /** - * serialize a fault - * - * @return string The serialization of the fault instance. - * @access public - */ - function serialize(){ - $ns_string = ''; - foreach($this->namespaces as $k => $v){ - $ns_string .= "\n xmlns:$k=\"$v\""; - } - $return_msg = - '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'. - '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n". - '<SOAP-ENV:Body>'. - '<SOAP-ENV:Fault>'. - $this->serialize_val($this->faultcode, 'faultcode'). - $this->serialize_val($this->faultactor, 'faultactor'). - $this->serialize_val($this->faultstring, 'faultstring'). - $this->serialize_val($this->faultdetail, 'detail'). - '</SOAP-ENV:Fault>'. - '</SOAP-ENV:Body>'. - '</SOAP-ENV:Envelope>'; - return $return_msg; - } -} - - - -?><?php - - - -/** -* parses an XML Schema, allows access to it's data, other utility methods -* no validation... yet. -* very experimental and limited. As is discussed on XML-DEV, I'm one of the people -* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty -* tutorials I refer to :) -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class XMLSchema extends nusoap_base { - - // files - var $schema = ''; - var $xml = ''; - // namespaces - var $enclosingNamespaces; - // schema info - var $schemaInfo = array(); - var $schemaTargetNamespace = ''; - // types, elements, attributes defined by the schema - var $attributes = array(); - var $complexTypes = array(); - var $complexTypeStack = array(); - var $currentComplexType = null; - var $elements = array(); - var $elementStack = array(); - var $currentElement = null; - var $simpleTypes = array(); - var $simpleTypeStack = array(); - var $currentSimpleType = null; - // imports - var $imports = array(); - // parser vars - var $parser; - var $position = 0; - var $depth = 0; - var $depth_array = array(); - var $message = array(); - var $defaultNamespace = array(); - - /** - * constructor - * - * @param string $schema schema document URI - * @param string $xml xml document URI - * @param string $namespaces namespaces defined in enclosing XML - * @access public - */ - function XMLSchema($schema='',$xml='',$namespaces=array()){ - parent::nusoap_base(); - $this->debug('xmlschema class instantiated, inside constructor'); - // files - $this->schema = $schema; - $this->xml = $xml; - - // namespaces - $this->enclosingNamespaces = $namespaces; - $this->namespaces = array_merge($this->namespaces, $namespaces); - - // parse schema file - if($schema != ''){ - $this->debug('initial schema file: '.$schema); - $this->parseFile($schema, 'schema'); - } - - // parse xml file - if($xml != ''){ - $this->debug('initial xml file: '.$xml); - $this->parseFile($xml, 'xml'); - } - - } - - /** - * parse an XML file - * - * @param string $xml, path/URL to XML file - * @param string $type, (schema | xml) - * @return boolean - * @access public - */ - function parseFile($xml,$type){ - // parse xml file - if($xml != ""){ - $xmlStr = @join("",@file($xml)); - if($xmlStr == ""){ - $msg = 'Error reading XML from '.$xml; - $this->setError($msg); - $this->debug($msg); - return false; - } else { - $this->debug("parsing $xml"); - $this->parseString($xmlStr,$type); - $this->debug("done parsing $xml"); - return true; - } - } - return false; - } - - /** - * parse an XML string - * - * @param string $xml path or URL - * @param string $type, (schema|xml) - * @access private - */ - function parseString($xml,$type){ - // parse xml string - if($xml != ""){ - - // Create an XML parser. - $this->parser = xml_parser_create(); - // Set the options for parsing the XML data. - xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); - - // Set the object for the parser. - xml_set_object($this->parser, $this); - - // Set the element handlers for the parser. - if($type == "schema"){ - xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); - xml_set_character_data_handler($this->parser,'schemaCharacterData'); - } elseif($type == "xml"){ - xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); - xml_set_character_data_handler($this->parser,'xmlCharacterData'); - } - - // Parse the XML file. - if(!xml_parse($this->parser,$xml,true)){ - // Display an error message. - $errstr = sprintf('XML error parsing XML schema on line %d: %s', - xml_get_current_line_number($this->parser), - xml_error_string(xml_get_error_code($this->parser)) - ); - $this->debug($errstr); - $this->debug("XML payload:\n" . $xml); - $this->setError($errstr); - } - - xml_parser_free($this->parser); - } else{ - $this->debug('no xml passed to parseString()!!'); - $this->setError('no xml passed to parseString()!!'); - } - } - - /** - * start-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @param string $attrs associative array of attributes - * @access private - */ - function schemaStartElement($parser, $name, $attrs) { - - // position in the total number of elements, starting from 0 - $pos = $this->position++; - $depth = $this->depth++; - // set self as current value for this depth - $this->depth_array[$depth] = $pos; - $this->message[$pos] = array('cdata' => ''); - if ($depth > 0) { - $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; - } else { - $this->defaultNamespace[$pos] = false; - } - - // get element prefix - if($prefix = $this->getPrefix($name)){ - // get unqualified name - $name = $this->getLocalPart($name); - } else { - $prefix = ''; - } - - // loop thru attributes, expanding, and registering namespace declarations - if(count($attrs) > 0){ - foreach($attrs as $k => $v){ - // if ns declarations, add to class level array of valid namespaces - if(ereg("^xmlns",$k)){ - //$this->xdebug("$k: $v"); - //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); - if($ns_prefix = substr(strrchr($k,':'),1)){ - //$this->xdebug("Add namespace[$ns_prefix] = $v"); - $this->namespaces[$ns_prefix] = $v; - } else { - $this->defaultNamespace[$pos] = $v; - if (! $this->getPrefixFromNamespace($v)) { - $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; - } - } - if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ - $this->XMLSchemaVersion = $v; - $this->namespaces['xsi'] = $v.'-instance'; - } - } - } - foreach($attrs as $k => $v){ - // expand each attribute - $k = strpos($k,':') ? $this->expandQname($k) : $k; - $v = strpos($v,':') ? $this->expandQname($v) : $v; - $eAttrs[$k] = $v; - } - $attrs = $eAttrs; - } else { - $attrs = array(); - } - // find status, register data - switch($name){ - case 'all': // (optional) compositor content for a complexType - case 'choice': - case 'group': - case 'sequence': - //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); - $this->complexTypes[$this->currentComplexType]['compositor'] = $name; - //if($name == 'all' || $name == 'sequence'){ - // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; - //} - break; - case 'attribute': // complexType attribute - //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); - $this->xdebug("parsing attribute:"); - $this->appendDebug($this->varDump($attrs)); - if (!isset($attrs['form'])) { - $attrs['form'] = $this->schemaInfo['attributeFormDefault']; - } - if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { - $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - if (!strpos($v, ':')) { - // no namespace in arrayType attribute value... - if ($this->defaultNamespace[$pos]) { - // ...so use the default - $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - } - } - } - if(isset($attrs['name'])){ - $this->attributes[$attrs['name']] = $attrs; - $aname = $attrs['name']; - } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ - if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { - $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - } else { - $aname = ''; - } - } elseif(isset($attrs['ref'])){ - $aname = $attrs['ref']; - $this->attributes[$attrs['ref']] = $attrs; - } - - if($this->currentComplexType){ // This should *always* be - $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; - } - // arrayType attribute - if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - $prefix = $this->getPrefix($aname); - if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ - $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; - } else { - $v = ''; - } - if(strpos($v,'[,]')){ - $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; - } - $v = substr($v,0,strpos($v,'[')); // clip the [] - if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ - $v = $this->XMLSchemaVersion.':'.$v; - } - $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; - } - break; - case 'complexContent': // (optional) content for a complexType - break; - case 'complexType': - array_push($this->complexTypeStack, $this->currentComplexType); - if(isset($attrs['name'])){ - $this->xdebug('processing named complexType '.$attrs['name']); - //$this->currentElement = false; - $this->currentComplexType = $attrs['name']; - $this->complexTypes[$this->currentComplexType] = $attrs; - $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; - // This is for constructs like - // <complexType name="ListOfString" base="soap:Array"> - // <sequence> - // <element name="string" type="xsd:string" - // minOccurs="0" maxOccurs="unbounded" /> - // </sequence> - // </complexType> - if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ - $this->xdebug('complexType is unusual array'); - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - } else { - $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; - } - }else{ - $this->xdebug('processing unnamed complexType for element '.$this->currentElement); - $this->currentComplexType = $this->currentElement . '_ContainedType'; - //$this->currentElement = false; - $this->complexTypes[$this->currentComplexType] = $attrs; - $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; - // This is for constructs like - // <complexType name="ListOfString" base="soap:Array"> - // <sequence> - // <element name="string" type="xsd:string" - // minOccurs="0" maxOccurs="unbounded" /> - // </sequence> - // </complexType> - if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ - $this->xdebug('complexType is unusual array'); - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - } else { - $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; - } - } - break; - case 'element': - array_push($this->elementStack, $this->currentElement); - // elements defined as part of a complex type should - // not really be added to $this->elements, but for some - // reason, they are - if (!isset($attrs['form'])) { - $attrs['form'] = $this->schemaInfo['elementFormDefault']; - } - if(isset($attrs['type'])){ - $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); - if (! $this->getPrefix($attrs['type'])) { - if ($this->defaultNamespace[$pos]) { - $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; - $this->xdebug('used default namespace to make type ' . $attrs['type']); - } - } - // This is for constructs like - // <complexType name="ListOfString" base="soap:Array"> - // <sequence> - // <element name="string" type="xsd:string" - // minOccurs="0" maxOccurs="unbounded" /> - // </sequence> - // </complexType> - if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { - $this->xdebug('arrayType for unusual array is ' . $attrs['type']); - $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; - } - $this->currentElement = $attrs['name']; - $this->elements[ $attrs['name'] ] = $attrs; - $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; - $ename = $attrs['name']; - } elseif(isset($attrs['ref'])){ - $this->xdebug("processing element as ref to ".$attrs['ref']); - $this->currentElement = "ref to ".$attrs['ref']; - $ename = $this->getLocalPart($attrs['ref']); - } else { - $this->xdebug("processing untyped element ".$attrs['name']); - $this->currentElement = $attrs['name']; - $this->elements[ $attrs['name'] ] = $attrs; - $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; - $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; - $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; - $ename = $attrs['name']; - } - if(isset($ename) && $this->currentComplexType){ - $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; - } - break; - case 'enumeration': // restriction value list member - $this->xdebug('enumeration ' . $attrs['value']); - if ($this->currentSimpleType) { - $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; - } elseif ($this->currentComplexType) { - $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; - } - break; - case 'extension': // simpleContent or complexContent type extension - $this->xdebug('extension ' . $attrs['base']); - if ($this->currentComplexType) { - $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; - } - break; - case 'import': - if (isset($attrs['schemaLocation'])) { - //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); - $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); - } else { - //$this->xdebug('import namespace ' . $attrs['namespace']); - $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); - if (! $this->getPrefixFromNamespace($attrs['namespace'])) { - $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; - } - } - break; - case 'list': // simpleType value list - break; - case 'restriction': // simpleType, simpleContent or complexContent value restriction - $this->xdebug('restriction ' . $attrs['base']); - if($this->currentSimpleType){ - $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; - } elseif($this->currentComplexType){ - $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; - if(strstr($attrs['base'],':') == ':Array'){ - $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; - } - } - break; - case 'schema': - $this->schemaInfo = $attrs; - $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); - if (isset($attrs['targetNamespace'])) { - $this->schemaTargetNamespace = $attrs['targetNamespace']; - } - if (!isset($attrs['elementFormDefault'])) { - $this->schemaInfo['elementFormDefault'] = 'unqualified'; - } - if (!isset($attrs['attributeFormDefault'])) { - $this->schemaInfo['attributeFormDefault'] = 'unqualified'; - } - break; - case 'simpleContent': // (optional) content for a complexType - break; - case 'simpleType': - array_push($this->simpleTypeStack, $this->currentSimpleType); - if(isset($attrs['name'])){ - $this->xdebug("processing simpleType for name " . $attrs['name']); - $this->currentSimpleType = $attrs['name']; - $this->simpleTypes[ $attrs['name'] ] = $attrs; - $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; - $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; - } else { - $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); - $this->currentSimpleType = $this->currentElement . '_ContainedType'; - //$this->currentElement = false; - $this->simpleTypes[$this->currentSimpleType] = $attrs; - $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; - } - break; - case 'union': // simpleType type list - break; - default: - //$this->xdebug("do not have anything to do for element $name"); - } - } - - /** - * end-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @access private - */ - function schemaEndElement($parser, $name) { - // bring depth down a notch - $this->depth--; - // position of current element is equal to the last value left in depth_array for my depth - if(isset($this->depth_array[$this->depth])){ - $pos = $this->depth_array[$this->depth]; - } - // get element prefix - if ($prefix = $this->getPrefix($name)){ - // get unqualified name - $name = $this->getLocalPart($name); - } else { - $prefix = ''; - } - // move on... - if($name == 'complexType'){ - $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); - $this->currentComplexType = array_pop($this->complexTypeStack); - //$this->currentElement = false; - } - if($name == 'element'){ - $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); - $this->currentElement = array_pop($this->elementStack); - } - if($name == 'simpleType'){ - $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); - $this->currentSimpleType = array_pop($this->simpleTypeStack); - } - } - - /** - * element content handler - * - * @param string $parser XML parser object - * @param string $data element content - * @access private - */ - function schemaCharacterData($parser, $data){ - $pos = $this->depth_array[$this->depth - 1]; - $this->message[$pos]['cdata'] .= $data; - } - - /** - * serialize the schema - * - * @access public - */ - function serializeSchema(){ - - $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); - $xml = ''; - // imports - if (sizeof($this->imports) > 0) { - foreach($this->imports as $ns => $list) { - foreach ($list as $ii) { - if ($ii['location'] != '') { - $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; - } else { - $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; - } - } - } - } - // complex types - foreach($this->complexTypes as $typeName => $attrs){ - $contentStr = ''; - // serialize child elements - if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ - foreach($attrs['elements'] as $element => $eParts){ - if(isset($eParts['ref'])){ - $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; - } else { - $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; - foreach ($eParts as $aName => $aValue) { - // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable - if ($aName != 'name' && $aName != 'type') { - $contentStr .= " $aName=\"$aValue\""; - } - } - $contentStr .= "/>\n"; - } - } - // compositor wraps elements - if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { - $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n"; - } - } - // attributes - if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ - foreach($attrs['attrs'] as $attr => $aParts){ - $contentStr .= " <$schemaPrefix:attribute"; - foreach ($aParts as $a => $v) { - if ($a == 'ref' || $a == 'type') { - $contentStr .= " $a=\"".$this->contractQName($v).'"'; - } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { - $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; - $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; - } else { - $contentStr .= " $a=\"$v\""; - } - } - $contentStr .= "/>\n"; - } - } - // if restriction - if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ - $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n"; - // complex or simple content - if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ - $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n"; - } - } - // finalize complex type - if($contentStr != ''){ - $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n"; - } else { - $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; - } - $xml .= $contentStr; - } - // simple types - if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ - foreach($this->simpleTypes as $typeName => $eParts){ - $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; - if (isset($eParts['enumeration'])) { - foreach ($eParts['enumeration'] as $e) { - $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; - } - } - $xml .= " </$schemaPrefix:simpleType>"; - } - } - // elements - if(isset($this->elements) && count($this->elements) > 0){ - foreach($this->elements as $element => $eParts){ - $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; - } - } - // attributes - if(isset($this->attributes) && count($this->attributes) > 0){ - foreach($this->attributes as $attr => $aParts){ - $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; - } - } - // finish 'er up - $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; - foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { - $el .= " xmlns:$nsp=\"$ns\"\n"; - } - $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n"; - return $xml; - } - - /** - * adds debug data to the clas level debug string - * - * @param string $string debug data - * @access private - */ - function xdebug($string){ - $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); - } - - /** - * get the PHP type of a user defined type in the schema - * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays - * returns false if no type exists, or not w/ the given namespace - * else returns a string that is either a native php type, or 'struct' - * - * @param string $type, name of defined type - * @param string $ns, namespace of type - * @return mixed - * @access public - * @deprecated - */ - function getPHPType($type,$ns){ - if(isset($this->typemap[$ns][$type])){ - //print "found type '$type' and ns $ns in typemap<br>"; - return $this->typemap[$ns][$type]; - } elseif(isset($this->complexTypes[$type])){ - //print "getting type '$type' and ns $ns from complexTypes array<br>"; - return $this->complexTypes[$type]['phpType']; - } - return false; - } - - /** - * returns an associative array of information about a given type - * returns false if no type exists by the given name - * - * For a complexType typeDef = array( - * 'restrictionBase' => '', - * 'phpType' => '', - * 'compositor' => '(sequence|all)', - * 'elements' => array(), // refs to elements array - * 'attrs' => array() // refs to attributes array - * ... and so on (see addComplexType) - * ) - * - * For simpleType or element, the array has different keys. - * - * @param string - * @return mixed - * @access public - * @see addComplexType - * @see addSimpleType - * @see addElement - */ - function getTypeDef($type){ - //$this->debug("in getTypeDef for type $type"); - if(isset($this->complexTypes[$type])){ - $this->xdebug("in getTypeDef, found complexType $type"); - return $this->complexTypes[$type]; - } elseif(isset($this->simpleTypes[$type])){ - $this->xdebug("in getTypeDef, found simpleType $type"); - if (!isset($this->simpleTypes[$type]['phpType'])) { - // get info for type to tack onto the simple type - // TODO: can this ever really apply (i.e. what is a simpleType really?) - $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); - $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); - $etype = $this->getTypeDef($uqType); - if ($etype) { - $this->xdebug("in getTypeDef, found type for simpleType $type:"); - $this->xdebug($this->varDump($etype)); - if (isset($etype['phpType'])) { - $this->simpleTypes[$type]['phpType'] = $etype['phpType']; - } - if (isset($etype['elements'])) { - $this->simpleTypes[$type]['elements'] = $etype['elements']; - } - } - } - return $this->simpleTypes[$type]; - } elseif(isset($this->elements[$type])){ - $this->xdebug("in getTypeDef, found element $type"); - if (!isset($this->elements[$type]['phpType'])) { - // get info for type to tack onto the element - $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); - $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); - $etype = $this->getTypeDef($uqType); - if ($etype) { - $this->xdebug("in getTypeDef, found type for element $type:"); - $this->xdebug($this->varDump($etype)); - if (isset($etype['phpType'])) { - $this->elements[$type]['phpType'] = $etype['phpType']; - } - if (isset($etype['elements'])) { - $this->elements[$type]['elements'] = $etype['elements']; - } - } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { - $this->xdebug("in getTypeDef, element $type is an XSD type"); - $this->elements[$type]['phpType'] = 'scalar'; - } - } - return $this->elements[$type]; - } elseif(isset($this->attributes[$type])){ - $this->xdebug("in getTypeDef, found attribute $type"); - return $this->attributes[$type]; - } elseif (ereg('_ContainedType$', $type)) { - $this->xdebug("in getTypeDef, have an untyped element $type"); - $typeDef['typeClass'] = 'simpleType'; - $typeDef['phpType'] = 'scalar'; - $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; - return $typeDef; - } - $this->xdebug("in getTypeDef, did not find $type"); - return false; - } - - /** - * returns a sample serialization of a given type, or false if no type by the given name - * - * @param string $type, name of type - * @return mixed - * @access public - * @deprecated - */ - function serializeTypeDef($type){ - //print "in sTD() for type $type<br>"; - if($typeDef = $this->getTypeDef($type)){ - $str .= '<'.$type; - if(is_array($typeDef['attrs'])){ - foreach($attrs as $attName => $data){ - $str .= " $attName=\"{type = ".$data['type']."}\""; - } - } - $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; - if(count($typeDef['elements']) > 0){ - $str .= ">"; - foreach($typeDef['elements'] as $element => $eData){ - $str .= $this->serializeTypeDef($element); - } - $str .= "</$type>"; - } elseif($typeDef['typeClass'] == 'element') { - $str .= "></$type>"; - } else { - $str .= "/>"; - } - return $str; - } - return false; - } - - /** - * returns HTML form elements that allow a user - * to enter values for creating an instance of the given type. - * - * @param string $name, name for type instance - * @param string $type, name of type - * @return string - * @access public - * @deprecated - */ - function typeToForm($name,$type){ - // get typedef - if($typeDef = $this->getTypeDef($type)){ - // if struct - if($typeDef['phpType'] == 'struct'){ - $buffer .= '<table>'; - foreach($typeDef['elements'] as $child => $childDef){ - $buffer .= " - <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td> - <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>"; - } - $buffer .= '</table>'; - // if array - } elseif($typeDef['phpType'] == 'array'){ - $buffer .= '<table>'; - for($i=0;$i < 3; $i++){ - $buffer .= " - <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> - <td><input type='text' name='parameters[".$name."][]'></td></tr>"; - } - $buffer .= '</table>'; - // if scalar - } else { - $buffer .= "<input type='text' name='parameters[$name]'>"; - } - } else { - $buffer .= "<input type='text' name='parameters[$name]'>"; - } - return $buffer; - } - - /** - * adds a complex type to the schema - * - * example: array - * - * addType( - * 'ArrayOfstring', - * 'complexType', - * 'array', - * '', - * 'SOAP-ENC:Array', - * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), - * 'xsd:string' - * ); - * - * example: PHP associative array ( SOAP Struct ) - * - * addType( - * 'SOAPStruct', - * 'complexType', - * 'struct', - * 'all', - * array('myVar'=> array('name'=>'myVar','type'=>'string') - * ); - * - * @param name - * @param typeClass (complexType|simpleType|attribute) - * @param phpType: currently supported are array and struct (php assoc array) - * @param compositor (all|sequence|choice) - * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param elements = array ( name = array(name=>'',type=>'') ) - * @param attrs = array( - * array( - * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", - * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" - * ) - * ) - * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) - * @access public - * @see getTypeDef - */ - function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ - $this->complexTypes[$name] = array( - 'name' => $name, - 'typeClass' => $typeClass, - 'phpType' => $phpType, - 'compositor'=> $compositor, - 'restrictionBase' => $restrictionBase, - 'elements' => $elements, - 'attrs' => $attrs, - 'arrayType' => $arrayType - ); - - $this->xdebug("addComplexType $name:"); - $this->appendDebug($this->varDump($this->complexTypes[$name])); - } - - /** - * adds a simple type to the schema - * - * @param string $name - * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param string $typeClass (should always be simpleType) - * @param string $phpType (should always be scalar) - * @param array $enumeration array of values - * @access public - * @see xmlschema - * @see getTypeDef - */ - function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { - $this->simpleTypes[$name] = array( - 'name' => $name, - 'typeClass' => $typeClass, - 'phpType' => $phpType, - 'type' => $restrictionBase, - 'enumeration' => $enumeration - ); - - $this->xdebug("addSimpleType $name:"); - $this->appendDebug($this->varDump($this->simpleTypes[$name])); - } - - /** - * adds an element to the schema - * - * @param array $attrs attributes that must include name and type - * @see xmlschema - * @access public - */ - function addElement($attrs) { - if (! $this->getPrefix($attrs['type'])) { - $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; - } - $this->elements[ $attrs['name'] ] = $attrs; - $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; - - $this->xdebug("addElement " . $attrs['name']); - $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); - } -} - - - -?><?php - - - -/** -* For creating serializable abstractions of native PHP types. This class -* allows element name/namespace, XSD type, and XML attributes to be -* associated with a value. This is extremely useful when WSDL is not -* used, but is also useful when WSDL is used with polymorphic types, including -* xsd:anyType and user-defined types. -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soapval extends nusoap_base { - /** - * The XML element name - * - * @var string - * @access private - */ - var $name; - /** - * The XML type name (string or false) - * - * @var mixed - * @access private - */ - var $type; - /** - * The PHP value - * - * @var mixed - * @access private - */ - var $value; - /** - * The XML element namespace (string or false) - * - * @var mixed - * @access private - */ - var $element_ns; - /** - * The XML type namespace (string or false) - * - * @var mixed - * @access private - */ - var $type_ns; - /** - * The XML element attributes (array or false) - * - * @var mixed - * @access private - */ - var $attributes; - - /** - * constructor - * - * @param string $name optional name - * @param mixed $type optional type name - * @param mixed $value optional value - * @param mixed $element_ns optional namespace of value - * @param mixed $type_ns optional namespace of type - * @param mixed $attributes associative array of attributes to add to element serialization - * @access public - */ - function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { - parent::nusoap_base(); - $this->name = $name; - $this->type = $type; - $this->value = $value; - $this->element_ns = $element_ns; - $this->type_ns = $type_ns; - $this->attributes = $attributes; - } - - /** - * return serialized value - * - * @param string $use The WSDL use value (encoded|literal) - * @return string XML data - * @access public - */ - function serialize($use='encoded') { - return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); - } - - /** - * decodes a soapval object into a PHP native type - * - * @return mixed - * @access public - */ - function decode(){ - return $this->value; - } -} - - - -?><?php - - - -/** -* transport class for sending/receiving data via HTTP and HTTPS -* NOTE: PHP must be compiled with the CURL extension for HTTPS support -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_transport_http extends nusoap_base { - - var $url = ''; - var $uri = ''; - var $digest_uri = ''; - var $scheme = ''; - var $host = ''; - var $port = ''; - var $path = ''; - var $request_method = 'POST'; - var $protocol_version = '1.0'; - var $encoding = ''; - var $outgoing_headers = array(); - var $incoming_headers = array(); - var $incoming_cookies = array(); - var $outgoing_payload = ''; - var $incoming_payload = ''; - var $useSOAPAction = true; - var $persistentConnection = false; - var $ch = false; // cURL handle - var $username = ''; - var $password = ''; - var $authtype = ''; - var $digestRequest = array(); - var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) - // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' - // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' - // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' - // passphrase: SSL key password/passphrase - // verifypeer: default is 1 - // verifyhost: default is 1 - - /** - * constructor - */ - function soap_transport_http($url){ - parent::nusoap_base(); - $this->setURL($url); - ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); - $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; - $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); - } - - function setURL($url) { - $this->url = $url; - - $u = parse_url($url); - foreach($u as $k => $v){ - $this->debug("$k = $v"); - $this->$k = $v; - } - - // add any GET params to path - if(isset($u['query']) && $u['query'] != ''){ - $this->path .= '?' . $u['query']; - } - - // set default port - if(!isset($u['port'])){ - if($u['scheme'] == 'https'){ - $this->port = 443; - } else { - $this->port = 80; - } - } - - $this->uri = $this->path; - $this->digest_uri = $this->uri; - - // build headers - if (!isset($u['port'])) { - $this->outgoing_headers['Host'] = $this->host; - } else { - $this->outgoing_headers['Host'] = $this->host.':'.$this->port; - } - $this->debug('set Host: ' . $this->outgoing_headers['Host']); - - if (isset($u['user']) && $u['user'] != '') { - $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); - } - } - - function connect($connection_timeout=0,$response_timeout=30){ - // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like - // "regular" socket. - // TODO: disabled for now because OpenSSL must be *compiled* in (not just - // loaded), and until PHP5 stream_get_wrappers is not available. -// if ($this->scheme == 'https') { -// if (version_compare(phpversion(), '4.3.0') >= 0) { -// if (extension_loaded('openssl')) { -// $this->scheme = 'ssl'; -// $this->debug('Using SSL over OpenSSL'); -// } -// } -// } - $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); - if ($this->scheme == 'http' || $this->scheme == 'ssl') { - // use persistent connection - if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ - if (!feof($this->fp)) { - $this->debug('Re-use persistent connection'); - return true; - } - fclose($this->fp); - $this->debug('Closed persistent connection at EOF'); - } - - // munge host if using OpenSSL - if ($this->scheme == 'ssl') { - $host = 'ssl://' . $this->host; - } else { - $host = $this->host; - } - $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); - - // open socket - if($connection_timeout > 0){ - $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); - } else { - $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); - } - - // test pointer - if(!$this->fp) { - $msg = 'Couldn\'t open socket connection to server ' . $this->url; - if ($this->errno) { - $msg .= ', Error ('.$this->errno.'): '.$this->error_str; - } else { - $msg .= ' prior to connect(). This is often a problem looking up the host name.'; - } - $this->debug($msg); - $this->setError($msg); - return false; - } - - // set response timeout - $this->debug('set response timeout to ' . $response_timeout); - socket_set_timeout( $this->fp, $response_timeout); - - $this->debug('socket connected'); - return true; - } else if ($this->scheme == 'https') { - if (!extension_loaded('curl')) { - $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); - return false; - } - $this->debug('connect using https'); - // init CURL - $this->ch = curl_init(); - // set url - $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; - // add path - $hostURL .= $this->path; - curl_setopt($this->ch, CURLOPT_URL, $hostURL); - // follow location headers (re-directs) - curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); - // ask for headers in the response output - curl_setopt($this->ch, CURLOPT_HEADER, 1); - // ask for the response output as the return value - curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); - // encode - // We manage this ourselves through headers and encoding -// if(function_exists('gzuncompress')){ -// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); -// } - // persistent connection - if ($this->persistentConnection) { - // The way we send data, we cannot use persistent connections, since - // there will be some "junk" at the end of our request. - //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); - $this->persistentConnection = false; - $this->outgoing_headers['Connection'] = 'close'; - $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); - } - // set timeout - if ($connection_timeout != 0) { - curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); - } - // TODO: cURL has added a connection timeout separate from the response timeout - //if ($connection_timeout != 0) { - // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); - //} - //if ($response_timeout != 0) { - // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); - //} - - // recent versions of cURL turn on peer/host checking by default, - // while PHP binaries are not compiled with a default location for the - // CA cert bundle, so disable peer/host checking. -//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); - curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); - - // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) - if ($this->authtype == 'certificate') { - if (isset($this->certRequest['cainfofile'])) { - curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); - } - if (isset($this->certRequest['verifypeer'])) { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); - } else { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); - } - if (isset($this->certRequest['verifyhost'])) { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); - } else { - curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); - } - if (isset($this->certRequest['sslcertfile'])) { - curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); - } - if (isset($this->certRequest['sslkeyfile'])) { - curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); - } - if (isset($this->certRequest['passphrase'])) { - curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); - } - } - $this->debug('cURL connection set up'); - return true; - } else { - $this->setError('Unknown scheme ' . $this->scheme); - $this->debug('Unknown scheme ' . $this->scheme); - return false; - } - } - - /** - * send the SOAP message via HTTP - * - * @param string $data message data - * @param integer $timeout set connection timeout in seconds - * @param integer $response_timeout set response timeout in seconds - * @param array $cookies cookies to send - * @return string data - * @access public - */ - function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { - - $this->debug('entered send() with data of length: '.strlen($data)); - - $this->tryagain = true; - $tries = 0; - while ($this->tryagain) { - $this->tryagain = false; - if ($tries++ < 2) { - // make connnection - if (!$this->connect($timeout, $response_timeout)){ - return false; - } - - // send request - if (!$this->sendRequest($data, $cookies)){ - return false; - } - - // get response - $respdata = $this->getResponse(); - } else { - $this->setError('Too many tries to get an OK response'); - } - } - $this->debug('end of send()'); - return $respdata; - } - - - /** - * send the SOAP message via HTTPS 1.0 using CURL - * - * @param string $msg message data - * @param integer $timeout set connection timeout in seconds - * @param integer $response_timeout set response timeout in seconds - * @param array $cookies cookies to send - * @return string data - * @access public - */ - function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { - return $this->send($data, $timeout, $response_timeout, $cookies); - } - - /** - * if authenticating, set user credentials here - * - * @param string $username - * @param string $password - * @param string $authtype (basic, digest, certificate) - * @param array $digestRequest (keys must be nonce, nc, realm, qop) - * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) - * @access public - */ - function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { - $this->debug("Set credentials for authtype $authtype"); - // cf. RFC 2617 - if ($authtype == 'basic') { - $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); - } elseif ($authtype == 'digest') { - if (isset($digestRequest['nonce'])) { - $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; - - // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) - - // A1 = unq(username-value) ":" unq(realm-value) ":" passwd - $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; - - // H(A1) = MD5(A1) - $HA1 = md5($A1); - - // A2 = Method ":" digest-uri-value - $A2 = 'POST:' . $this->digest_uri; - - // H(A2) - $HA2 = md5($A2); - - // KD(secret, data) = H(concat(secret, ":", data)) - // if qop == auth: - // request-digest = <"> < KD ( H(A1), unq(nonce-value) - // ":" nc-value - // ":" unq(cnonce-value) - // ":" unq(qop-value) - // ":" H(A2) - // ) <"> - // if qop is missing, - // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> - - $unhashedDigest = ''; - $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; - $cnonce = $nonce; - if ($digestRequest['qop'] != '') { - $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; - } else { - $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; - } - - $hashedDigest = md5($unhashedDigest); - - $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; - } - } elseif ($authtype == 'certificate') { - $this->certRequest = $certRequest; - } - $this->username = $username; - $this->password = $password; - $this->authtype = $authtype; - $this->digestRequest = $digestRequest; - - if (isset($this->outgoing_headers['Authorization'])) { - $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); - } else { - $this->debug('Authorization header not set'); - } - } - - /** - * set the soapaction value - * - * @param string $soapaction - * @access public - */ - function setSOAPAction($soapaction) { - $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; - $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); - } - - /** - * use http encoding - * - * @param string $enc encoding style. supported values: gzip, deflate, or both - * @access public - */ - function setEncoding($enc='gzip, deflate') { - if (function_exists('gzdeflate')) { - $this->protocol_version = '1.1'; - $this->outgoing_headers['Accept-Encoding'] = $enc; - $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); - if (!isset($this->outgoing_headers['Connection'])) { - $this->outgoing_headers['Connection'] = 'close'; - $this->persistentConnection = false; - $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); - } - set_magic_quotes_runtime(0); - // deprecated - $this->encoding = $enc; - } - } - - /** - * set proxy info here - * - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @access public - */ - function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { - $this->uri = $this->url; - $this->host = $proxyhost; - $this->port = $proxyport; - if ($proxyusername != '' && $proxypassword != '') { - $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); - $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); - } - } - - /** - * decode a string that is encoded w/ "chunked' transfer encoding - * as defined in RFC2068 19.4.6 - * - * @param string $buffer - * @param string $lb - * @returns string - * @access public - * @deprecated - */ - function decodeChunked($buffer, $lb){ - // length := 0 - $length = 0; - $new = ''; - - // read chunk-size, chunk-extension (if any) and CRLF - // get the position of the linebreak - $chunkend = strpos($buffer, $lb); - if ($chunkend == FALSE) { - $this->debug('no linebreak found in decodeChunked'); - return $new; - } - $temp = substr($buffer,0,$chunkend); - $chunk_size = hexdec( trim($temp) ); - $chunkstart = $chunkend + strlen($lb); - // while (chunk-size > 0) { - while ($chunk_size > 0) { - $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); - $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); - - // Just in case we got a broken connection - if ($chunkend == FALSE) { - $chunk = substr($buffer,$chunkstart); - // append chunk-data to entity-body - $new .= $chunk; - $length += strlen($chunk); - break; - } - - // read chunk-data and CRLF - $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); - // append chunk-data to entity-body - $new .= $chunk; - // length := length + chunk-size - $length += strlen($chunk); - // read chunk-size and CRLF - $chunkstart = $chunkend + strlen($lb); - - $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); - if ($chunkend == FALSE) { - break; //Just in case we got a broken connection - } - $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); - $chunk_size = hexdec( trim($temp) ); - $chunkstart = $chunkend; - } - return $new; - } - - /* - * Writes payload, including HTTP headers, to $this->outgoing_payload. - */ - function buildPayload($data, $cookie_str = '') { - // add content-length header - $this->outgoing_headers['Content-Length'] = strlen($data); - $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); - - // start building outgoing payload: - $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; - $this->debug("HTTP request: $req"); - $this->outgoing_payload = "$req\r\n"; - - // loop thru headers, serializing - foreach($this->outgoing_headers as $k => $v){ - $hdr = $k.': '.$v; - $this->debug("HTTP header: $hdr"); - $this->outgoing_payload .= "$hdr\r\n"; - } - - // add any cookies - if ($cookie_str != '') { - $hdr = 'Cookie: '.$cookie_str; - $this->debug("HTTP header: $hdr"); - $this->outgoing_payload .= "$hdr\r\n"; - } - - // header/body separator - $this->outgoing_payload .= "\r\n"; - - // add data - $this->outgoing_payload .= $data; - } - - function sendRequest($data, $cookies = NULL) { - // build cookie string - $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); - - // build payload - $this->buildPayload($data, $cookie_str); - - if ($this->scheme == 'http' || $this->scheme == 'ssl') { - // send payload - if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { - $this->setError('couldn\'t write message data to socket'); - $this->debug('couldn\'t write message data to socket'); - return false; - } - $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); - return true; - } else if ($this->scheme == 'https') { - // set payload - // TODO: cURL does say this should only be the verb, and in fact it - // turns out that the URI and HTTP version are appended to this, which - // some servers refuse to work with - //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); - foreach($this->outgoing_headers as $k => $v){ - $curl_headers[] = "$k: $v"; - } - if ($cookie_str != '') { - $curl_headers[] = 'Cookie: ' . $cookie_str; - } - curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); - if ($this->request_method == "POST") { - curl_setopt($this->ch, CURLOPT_POST, 1); - curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); - } else { - } - $this->debug('set cURL payload'); - return true; - } - } - - function getResponse(){ - $this->incoming_payload = ''; - - if ($this->scheme == 'http' || $this->scheme == 'ssl') { - // loop until headers have been retrieved - $data = ''; - while (!isset($lb)){ - - // We might EOF during header read. - if(feof($this->fp)) { - $this->incoming_payload = $data; - $this->debug('found no headers before EOF after length ' . strlen($data)); - $this->debug("received before EOF:\n" . $data); - $this->setError('server failed to send headers'); - return false; - } - - $tmp = fgets($this->fp, 256); - $tmplen = strlen($tmp); - $this->debug("read line of $tmplen bytes: " . trim($tmp)); - - if ($tmplen == 0) { - $this->incoming_payload = $data; - $this->debug('socket read of headers timed out after length ' . strlen($data)); - $this->debug("read before timeout: " . $data); - $this->setError('socket read of headers timed out'); - return false; - } - - $data .= $tmp; - $pos = strpos($data,"\r\n\r\n"); - if($pos > 1){ - $lb = "\r\n"; - } else { - $pos = strpos($data,"\n\n"); - if($pos > 1){ - $lb = "\n"; - } - } - // remove 100 header - if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ - unset($lb); - $data = ''; - }// - } - // store header data - $this->incoming_payload .= $data; - $this->debug('found end of headers after length ' . strlen($data)); - // process headers - $header_data = trim(substr($data,0,$pos)); - $header_array = explode($lb,$header_data); - $this->incoming_headers = array(); - $this->incoming_cookies = array(); - foreach($header_array as $header_line){ - $arr = explode(':',$header_line, 2); - if(count($arr) > 1){ - $header_name = strtolower(trim($arr[0])); - $this->incoming_headers[$header_name] = trim($arr[1]); - if ($header_name == 'set-cookie') { - // TODO: allow multiple cookies from parseCookie - $cookie = $this->parseCookie(trim($arr[1])); - if ($cookie) { - $this->incoming_cookies[] = $cookie; - $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); - } else { - $this->debug('did not find cookie in ' . trim($arr[1])); - } - } - } else if (isset($header_name)) { - // append continuation line to previous header - $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; - } - } - - // loop until msg has been received - if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { - $content_length = 2147483647; // ignore any content-length header - $chunked = true; - $this->debug("want to read chunked content"); - } elseif (isset($this->incoming_headers['content-length'])) { - $content_length = $this->incoming_headers['content-length']; - $chunked = false; - $this->debug("want to read content of length $content_length"); - } else { - $content_length = 2147483647; - $chunked = false; - $this->debug("want to read content to EOF"); - } - $data = ''; - do { - if ($chunked) { - $tmp = fgets($this->fp, 256); - $tmplen = strlen($tmp); - $this->debug("read chunk line of $tmplen bytes"); - if ($tmplen == 0) { - $this->incoming_payload = $data; - $this->debug('socket read of chunk length timed out after length ' . strlen($data)); - $this->debug("read before timeout:\n" . $data); - $this->setError('socket read of chunk length timed out'); - return false; - } - $content_length = hexdec(trim($tmp)); - $this->debug("chunk length $content_length"); - } - $strlen = 0; - while (($strlen < $content_length) && (!feof($this->fp))) { - $readlen = min(8192, $content_length - $strlen); - $tmp = fread($this->fp, $readlen); - $tmplen = strlen($tmp); - $this->debug("read buffer of $tmplen bytes"); - if (($tmplen == 0) && (!feof($this->fp))) { - $this->incoming_payload = $data; - $this->debug('socket read of body timed out after length ' . strlen($data)); - $this->debug("read before timeout:\n" . $data); - $this->setError('socket read of body timed out'); - return false; - } - $strlen += $tmplen; - $data .= $tmp; - } - if ($chunked && ($content_length > 0)) { - $tmp = fgets($this->fp, 256); - $tmplen = strlen($tmp); - $this->debug("read chunk terminator of $tmplen bytes"); - if ($tmplen == 0) { - $this->incoming_payload = $data; - $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); - $this->debug("read before timeout:\n" . $data); - $this->setError('socket read of chunk terminator timed out'); - return false; - } - } - } while ($chunked && ($content_length > 0) && (!feof($this->fp))); - if (feof($this->fp)) { - $this->debug('read to EOF'); - } - $this->debug('read body of length ' . strlen($data)); - $this->incoming_payload .= $data; - $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); - - // close filepointer - if( - (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || - (! $this->persistentConnection) || feof($this->fp)){ - fclose($this->fp); - $this->fp = false; - $this->debug('closed socket'); - } - - // connection was closed unexpectedly - if($this->incoming_payload == ''){ - $this->setError('no response from server'); - return false; - } - - // decode transfer-encoding -// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ -// if(!$data = $this->decodeChunked($data, $lb)){ -// $this->setError('Decoding of chunked data failed'); -// return false; -// } - //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>"; - // set decoded payload -// $this->incoming_payload = $header_data.$lb.$lb.$data; -// } - - } else if ($this->scheme == 'https') { - // send and receive - $this->debug('send and receive with cURL'); - $this->incoming_payload = curl_exec($this->ch); - $data = $this->incoming_payload; - - $cErr = curl_error($this->ch); - if ($cErr != '') { - $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>'; - // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE - foreach(curl_getinfo($this->ch) as $k => $v){ - $err .= "$k: $v<br>"; - } - $this->debug($err); - $this->setError($err); - curl_close($this->ch); - return false; - } else { - //echo '<pre>'; - //var_dump(curl_getinfo($this->ch)); - //echo '</pre>'; - } - // close curl - $this->debug('No cURL error, closing cURL'); - curl_close($this->ch); - - // remove 100 header(s) - while (ereg('^HTTP/1.1 100',$data)) { - if ($pos = strpos($data,"\r\n\r\n")) { - $data = ltrim(substr($data,$pos)); - } elseif($pos = strpos($data,"\n\n") ) { - $data = ltrim(substr($data,$pos)); - } - } - - // separate content from HTTP headers - if ($pos = strpos($data,"\r\n\r\n")) { - $lb = "\r\n"; - } elseif( $pos = strpos($data,"\n\n")) { - $lb = "\n"; - } else { - $this->debug('no proper separation of headers and document'); - $this->setError('no proper separation of headers and document'); - return false; - } - $header_data = trim(substr($data,0,$pos)); - $header_array = explode($lb,$header_data); - $data = ltrim(substr($data,$pos)); - $this->debug('found proper separation of headers and document'); - $this->debug('cleaned data, stringlen: '.strlen($data)); - // clean headers - foreach ($header_array as $header_line) { - $arr = explode(':',$header_line,2); - if(count($arr) > 1){ - $header_name = strtolower(trim($arr[0])); - $this->incoming_headers[$header_name] = trim($arr[1]); - if ($header_name == 'set-cookie') { - // TODO: allow multiple cookies from parseCookie - $cookie = $this->parseCookie(trim($arr[1])); - if ($cookie) { - $this->incoming_cookies[] = $cookie; - $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); - } else { - $this->debug('did not find cookie in ' . trim($arr[1])); - } - } - } else if (isset($header_name)) { - // append continuation line to previous header - $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; - } - } - } - - $arr = explode(' ', $header_array[0], 3); - $http_version = $arr[0]; - $http_status = intval($arr[1]); - $http_reason = count($arr) > 2 ? $arr[2] : ''; - - // see if we need to resend the request with http digest authentication - if (isset($this->incoming_headers['location']) && $http_status == 301) { - $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); - $this->setURL($this->incoming_headers['location']); - $this->tryagain = true; - return false; - } - - // see if we need to resend the request with http digest authentication - if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { - $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); - if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { - $this->debug('Server wants digest authentication'); - // remove "Digest " from our elements - $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); - - // parse elements into array - $digestElements = explode(',', $digestString); - foreach ($digestElements as $val) { - $tempElement = explode('=', trim($val), 2); - $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); - } - - // should have (at least) qop, realm, nonce - if (isset($digestRequest['nonce'])) { - $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); - $this->tryagain = true; - return false; - } - } - $this->debug('HTTP authentication failed'); - $this->setError('HTTP authentication failed'); - return false; - } - - if ( - ($http_status >= 300 && $http_status <= 307) || - ($http_status >= 400 && $http_status <= 417) || - ($http_status >= 501 && $http_status <= 505) - ) { - $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); - return false; - } - - // decode content-encoding - if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ - if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ - // if decoding works, use it. else assume data wasn't gzencoded - if(function_exists('gzinflate')){ - //$timer->setMarker('starting decoding of gzip/deflated content'); - // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) - // this means there are no Zlib headers, although there should be - $this->debug('The gzinflate function exists'); - $datalen = strlen($data); - if ($this->incoming_headers['content-encoding'] == 'deflate') { - if ($degzdata = @gzinflate($data)) { - $data = $degzdata; - $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); - if (strlen($data) < $datalen) { - // test for the case that the payload has been compressed twice - $this->debug('The inflated payload is smaller than the gzipped one; try again'); - if ($degzdata = @gzinflate($data)) { - $data = $degzdata; - $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); - } - } - } else { - $this->debug('Error using gzinflate to inflate the payload'); - $this->setError('Error using gzinflate to inflate the payload'); - } - } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { - if ($degzdata = @gzinflate(substr($data, 10))) { // do our best - $data = $degzdata; - $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); - if (strlen($data) < $datalen) { - // test for the case that the payload has been compressed twice - $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); - if ($degzdata = @gzinflate(substr($data, 10))) { - $data = $degzdata; - $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); - } - } - } else { - $this->debug('Error using gzinflate to un-gzip the payload'); - $this->setError('Error using gzinflate to un-gzip the payload'); - } - } - //$timer->setMarker('finished decoding of gzip/deflated content'); - //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>"; - // set decoded payload - $this->incoming_payload = $header_data.$lb.$lb.$data; - } else { - $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); - $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); - } - } else { - $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); - $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); - } - } else { - $this->debug('No Content-Encoding header'); - } - - if(strlen($data) == 0){ - $this->debug('no data after headers!'); - $this->setError('no data present after HTTP headers'); - return false; - } - - return $data; - } - - function setContentType($type, $charset = false) { - $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); - $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); - } - - function usePersistentConnection(){ - if (isset($this->outgoing_headers['Accept-Encoding'])) { - return false; - } - $this->protocol_version = '1.1'; - $this->persistentConnection = true; - $this->outgoing_headers['Connection'] = 'Keep-Alive'; - $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); - return true; - } - - /** - * parse an incoming Cookie into it's parts - * - * @param string $cookie_str content of cookie - * @return array with data of that cookie - * @access private - */ - /* - * TODO: allow a Set-Cookie string to be parsed into multiple cookies - */ - function parseCookie($cookie_str) { - $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; - $data = split(';', $cookie_str); - $value_str = $data[0]; - - $cookie_param = 'domain='; - $start = strpos($cookie_str, $cookie_param); - if ($start > 0) { - $domain = substr($cookie_str, $start + strlen($cookie_param)); - $domain = substr($domain, 0, strpos($domain, ';')); - } else { - $domain = ''; - } - - $cookie_param = 'expires='; - $start = strpos($cookie_str, $cookie_param); - if ($start > 0) { - $expires = substr($cookie_str, $start + strlen($cookie_param)); - $expires = substr($expires, 0, strpos($expires, ';')); - } else { - $expires = ''; - } - - $cookie_param = 'path='; - $start = strpos($cookie_str, $cookie_param); - if ( $start > 0 ) { - $path = substr($cookie_str, $start + strlen($cookie_param)); - $path = substr($path, 0, strpos($path, ';')); - } else { - $path = '/'; - } - - $cookie_param = ';secure;'; - if (strpos($cookie_str, $cookie_param) !== FALSE) { - $secure = true; - } else { - $secure = false; - } - - $sep_pos = strpos($value_str, '='); - - if ($sep_pos) { - $name = substr($value_str, 0, $sep_pos); - $value = substr($value_str, $sep_pos + 1); - $cookie= array( 'name' => $name, - 'value' => $value, - 'domain' => $domain, - 'path' => $path, - 'expires' => $expires, - 'secure' => $secure - ); - return $cookie; - } - return false; - } - - /** - * sort out cookies for the current request - * - * @param array $cookies array with all cookies - * @param boolean $secure is the send-content secure or not? - * @return string for Cookie-HTTP-Header - * @access private - */ - function getCookiesForRequest($cookies, $secure=false) { - $cookie_str = ''; - if ((! is_null($cookies)) && (is_array($cookies))) { - foreach ($cookies as $cookie) { - if (! is_array($cookie)) { - continue; - } - $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); - if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { - if (strtotime($cookie['expires']) <= time()) { - $this->debug('cookie has expired'); - continue; - } - } - if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { - $domain = preg_quote($cookie['domain']); - if (! preg_match("'.*$domain$'i", $this->host)) { - $this->debug('cookie has different domain'); - continue; - } - } - if ((isset($cookie['path'])) && (! empty($cookie['path']))) { - $path = preg_quote($cookie['path']); - if (! preg_match("'^$path.*'i", $this->path)) { - $this->debug('cookie is for a different path'); - continue; - } - } - if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { - $this->debug('cookie is secure, transport is not'); - continue; - } - $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; - $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); - } - } - return $cookie_str; - } -} - -?><?php - - - -/** -* -* soap_server allows the user to create a SOAP server -* that is capable of receiving messages and returning responses -* -* NOTE: WSDL functionality is experimental -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_server extends nusoap_base { - /** - * HTTP headers of request - * @var array - * @access private - */ - var $headers = array(); - /** - * HTTP request - * @var string - * @access private - */ - var $request = ''; - /** - * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) - * @var string - * @access public - */ - var $requestHeaders = ''; - /** - * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) - * @var string - * @access public - */ - var $document = ''; - /** - * SOAP payload for request (text) - * @var string - * @access public - */ - var $requestSOAP = ''; - /** - * requested method namespace URI - * @var string - * @access private - */ - var $methodURI = ''; - /** - * name of method requested - * @var string - * @access private - */ - var $methodname = ''; - /** - * method parameters from request - * @var array - * @access private - */ - var $methodparams = array(); - /** - * SOAP Action from request - * @var string - * @access private - */ - var $SOAPAction = ''; - /** - * character set encoding of incoming (request) messages - * @var string - * @access public - */ - var $xml_encoding = ''; - /** - * toggles whether the parser decodes element content w/ utf8_decode() - * @var boolean - * @access public - */ - var $decode_utf8 = true; - - /** - * HTTP headers of response - * @var array - * @access public - */ - var $outgoing_headers = array(); - /** - * HTTP response - * @var string - * @access private - */ - var $response = ''; - /** - * SOAP headers for response (text) - * @var string - * @access public - */ - var $responseHeaders = ''; - /** - * SOAP payload for response (text) - * @var string - * @access private - */ - var $responseSOAP = ''; - /** - * method return value to place in response - * @var mixed - * @access private - */ - var $methodreturn = false; - /** - * whether $methodreturn is a string of literal XML - * @var boolean - * @access public - */ - var $methodreturnisliteralxml = false; - /** - * SOAP fault for response (or false) - * @var mixed - * @access private - */ - var $fault = false; - /** - * text indication of result (for debugging) - * @var string - * @access private - */ - var $result = 'successful'; - - /** - * assoc array of operations => opData; operations are added by the register() - * method or by parsing an external WSDL definition - * @var array - * @access private - */ - var $operations = array(); - /** - * wsdl instance (if one) - * @var mixed - * @access private - */ - var $wsdl = false; - /** - * URL for WSDL (if one) - * @var mixed - * @access private - */ - var $externalWSDLURL = false; - /** - * whether to append debug to response as XML comment - * @var boolean - * @access public - */ - var $debug_flag = false; - - - /** - * constructor - * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. - * - * @param mixed $wsdl file path or URL (string), or wsdl instance (object) - * @access public - */ - function soap_server($wsdl=false){ - parent::nusoap_base(); - // turn on debugging? - global $debug; - global $HTTP_SERVER_VARS; - - if (isset($_SERVER)) { - $this->debug("_SERVER is defined:"); - $this->appendDebug($this->varDump($_SERVER)); - } elseif (isset($HTTP_SERVER_VARS)) { - $this->debug("HTTP_SERVER_VARS is defined:"); - $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); - } else { - $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); - } - - if (isset($debug)) { - $this->debug("In soap_server, set debug_flag=$debug based on global flag"); - $this->debug_flag = $debug; - } elseif (isset($_SERVER['QUERY_STRING'])) { - $qs = explode('&', $_SERVER['QUERY_STRING']); - foreach ($qs as $v) { - if (substr($v, 0, 6) == 'debug=') { - $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); - $this->debug_flag = substr($v, 6); - } - } - } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { - $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); - foreach ($qs as $v) { - if (substr($v, 0, 6) == 'debug=') { - $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); - $this->debug_flag = substr($v, 6); - } - } - } - - // wsdl - if($wsdl){ - $this->debug("In soap_server, WSDL is specified"); - if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { - $this->wsdl = $wsdl; - $this->externalWSDLURL = $this->wsdl->wsdl; - $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); - } else { - $this->debug('Create wsdl from ' . $wsdl); - $this->wsdl = new wsdl($wsdl); - $this->externalWSDLURL = $wsdl; - } - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - if($err = $this->wsdl->getError()){ - die('WSDL ERROR: '.$err); - } - } - } - - /** - * processes request and returns response - * - * @param string $data usually is the value of $HTTP_RAW_POST_DATA - * @access public - */ - function service($data){ - global $HTTP_SERVER_VARS; - - if (isset($_SERVER['QUERY_STRING'])) { - $qs = $_SERVER['QUERY_STRING']; - } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { - $qs = $HTTP_SERVER_VARS['QUERY_STRING']; - } else { - $qs = ''; - } - $this->debug("In service, query string=$qs"); - - if (ereg('wsdl', $qs) ){ - $this->debug("In service, this is a request for WSDL"); - if($this->externalWSDLURL){ - if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL - header('Location: '.$this->externalWSDLURL); - } else { // assume file - header("Content-Type: text/xml\r\n"); - $fp = fopen($this->externalWSDLURL, 'r'); - fpassthru($fp); - } - } elseif ($this->wsdl) { - header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); - print $this->wsdl->serialize($this->debug_flag); - if ($this->debug_flag) { - $this->debug('wsdl:'); - $this->appendDebug($this->varDump($this->wsdl)); - print $this->getDebugAsXMLComment(); - } - } else { - header("Content-Type: text/html; charset=ISO-8859-1\r\n"); - print "This service does not provide WSDL"; - } - } elseif ($data == '' && $this->wsdl) { - $this->debug("In service, there is no data, so return Web description"); - print $this->wsdl->webDescription(); - } else { - $this->debug("In service, invoke the request"); - $this->parse_request($data); - if (! $this->fault) { - $this->invoke_method(); - } - if (! $this->fault) { - $this->serialize_return(); - } - $this->send_response(); - } - } - - /** - * parses HTTP request headers. - * - * The following fields are set by this function (when successful) - * - * headers - * request - * xml_encoding - * SOAPAction - * - * @access private - */ - function parse_http_headers() { - global $HTTP_SERVER_VARS; - - $this->request = ''; - $this->SOAPAction = ''; - if(function_exists('getallheaders')){ - $this->debug("In parse_http_headers, use getallheaders"); - $headers = getallheaders(); - foreach($headers as $k=>$v){ - $k = strtolower($k); - $this->headers[$k] = $v; - $this->request .= "$k: $v\r\n"; - $this->debug("$k: $v"); - } - // get SOAPAction header - if(isset($this->headers['soapaction'])){ - $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); - } - // get the character encoding of the incoming request - if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ - $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); - if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - } elseif(isset($_SERVER) && is_array($_SERVER)){ - $this->debug("In parse_http_headers, use _SERVER"); - foreach ($_SERVER as $k => $v) { - if (substr($k, 0, 5) == 'HTTP_') { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); - } else { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); - } - if ($k == 'soapaction') { - // get SOAPAction header - $k = 'SOAPAction'; - $v = str_replace('"', '', $v); - $v = str_replace('\\', '', $v); - $this->SOAPAction = $v; - } else if ($k == 'content-type') { - // get the character encoding of the incoming request - if (strpos($v, '=')) { - $enc = substr(strstr($v, '='), 1); - $enc = str_replace('"', '', $enc); - $enc = str_replace('\\', '', $enc); - if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - } - $this->headers[$k] = $v; - $this->request .= "$k: $v\r\n"; - $this->debug("$k: $v"); - } - } elseif (is_array($HTTP_SERVER_VARS)) { - $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); - foreach ($HTTP_SERVER_VARS as $k => $v) { - if (substr($k, 0, 5) == 'HTTP_') { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); - } else { - $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); - } - if ($k == 'soapaction') { - // get SOAPAction header - $k = 'SOAPAction'; - $v = str_replace('"', '', $v); - $v = str_replace('\\', '', $v); - $this->SOAPAction = $v; - } else if ($k == 'content-type') { - // get the character encoding of the incoming request - if (strpos($v, '=')) { - $enc = substr(strstr($v, '='), 1); - $enc = str_replace('"', '', $enc); - $enc = str_replace('\\', '', $enc); - if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - } - $this->headers[$k] = $v; - $this->request .= "$k: $v\r\n"; - $this->debug("$k: $v"); - } - } else { - $this->debug("In parse_http_headers, HTTP headers not accessible"); - $this->setError("HTTP headers not accessible"); - } - } - - /** - * parses a request - * - * The following fields are set by this function (when successful) - * - * headers - * request - * xml_encoding - * SOAPAction - * request - * requestSOAP - * methodURI - * methodname - * methodparams - * requestHeaders - * document - * - * This sets the fault field on error - * - * @param string $data XML string - * @access private - */ - function parse_request($data='') { - $this->debug('entering parse_request()'); - $this->parse_http_headers(); - $this->debug('got character encoding: '.$this->xml_encoding); - // uncompress if necessary - if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { - $this->debug('got content encoding: ' . $this->headers['content-encoding']); - if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { - // if decoding works, use it. else assume data wasn't gzencoded - if (function_exists('gzuncompress')) { - if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { - $data = $degzdata; - } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { - $data = $degzdata; - } else { - $this->fault('Client', 'Errors occurred when trying to decode the data'); - return; - } - } else { - $this->fault('Client', 'This Server does not support compressed data'); - return; - } - } - } - $this->request .= "\r\n".$data; - $data = $this->parseRequest($this->headers, $data); - $this->requestSOAP = $data; - $this->debug('leaving parse_request'); - } - - /** - * invokes a PHP function for the requested SOAP method - * - * The following fields are set by this function (when successful) - * - * methodreturn - * - * Note that the PHP function that is called may also set the following - * fields to affect the response sent to the client - * - * responseHeaders - * outgoing_headers - * - * This sets the fault field on error - * - * @access private - */ - function invoke_method() { - $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); - - if ($this->wsdl) { - if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { - $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); - $this->appendDebug('opData=' . $this->varDump($this->opData)); - } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { - // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element - $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); - $this->appendDebug('opData=' . $this->varDump($this->opData)); - $this->methodname = $this->opData['name']; - } else { - $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); - $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); - return; - } - } else { - $this->debug('in invoke_method, no WSDL to validate method'); - } - - // if a . is present in $this->methodname, we see if there is a class in scope, - // which could be referred to. We will also distinguish between two deliminators, - // to allow methods to be called a the class or an instance - $class = ''; - $method = ''; - if (strpos($this->methodname, '..') > 0) { - $delim = '..'; - } else if (strpos($this->methodname, '.') > 0) { - $delim = '.'; - } else { - $delim = ''; - } - - if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && - class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { - // get the class and method name - $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); - $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); - $this->debug("in invoke_method, class=$class method=$method delim=$delim"); - } - - // does method exist? - if ($class == '') { - if (!function_exists($this->methodname)) { - $this->debug("in invoke_method, function '$this->methodname' not found!"); - $this->result = 'fault: method not found'; - $this->fault('Client',"method '$this->methodname' not defined in service"); - return; - } - } else { - $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; - if (!in_array($method_to_compare, get_class_methods($class))) { - $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); - $this->result = 'fault: method not found'; - $this->fault('Client',"method '$this->methodname' not defined in service"); - return; - } - } - - // evaluate message, getting back parameters - // verify that request parameters match the method's signature - if(! $this->verify_method($this->methodname,$this->methodparams)){ - // debug - $this->debug('ERROR: request not verified against method signature'); - $this->result = 'fault: request failed validation against method signature'; - // return fault - $this->fault('Client',"Operation '$this->methodname' not defined in service."); - return; - } - - // if there are parameters to pass - $this->debug('in invoke_method, params:'); - $this->appendDebug($this->varDump($this->methodparams)); - $this->debug("in invoke_method, calling '$this->methodname'"); - if (!function_exists('call_user_func_array')) { - if ($class == '') { - $this->debug('in invoke_method, calling function using eval()'); - $funcCall = "\$this->methodreturn = $this->methodname("; - } else { - if ($delim == '..') { - $this->debug('in invoke_method, calling class method using eval()'); - $funcCall = "\$this->methodreturn = ".$class."::".$method."("; - } else { - $this->debug('in invoke_method, calling instance method using eval()'); - // generate unique instance name - $instname = "\$inst_".time(); - $funcCall = $instname." = new ".$class."(); "; - $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; - } - } - if ($this->methodparams) { - foreach ($this->methodparams as $param) { - if (is_array($param)) { - $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); - return; - } - $funcCall .= "\"$param\","; - } - $funcCall = substr($funcCall, 0, -1); - } - $funcCall .= ');'; - $this->debug('in invoke_method, function call: '.$funcCall); - @eval($funcCall); - } else { - if ($class == '') { - $this->debug('in invoke_method, calling function using call_user_func_array()'); - $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() - } elseif ($delim == '..') { - $this->debug('in invoke_method, calling class method using call_user_func_array()'); - $call_arg = array ($class, $method); - } else { - $this->debug('in invoke_method, calling instance method using call_user_func_array()'); - $instance = new $class (); - $call_arg = array(&$instance, $method); - } - $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); - } - $this->debug('in invoke_method, methodreturn:'); - $this->appendDebug($this->varDump($this->methodreturn)); - $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); - } - - /** - * serializes the return value from a PHP function into a full SOAP Envelope - * - * The following fields are set by this function (when successful) - * - * responseSOAP - * - * This sets the fault field on error - * - * @access private - */ - function serialize_return() { - $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); - // if fault - if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) { - $this->debug('got a fault object from method'); - $this->fault = $this->methodreturn; - return; - } elseif ($this->methodreturnisliteralxml) { - $return_val = $this->methodreturn; - // returned value(s) - } else { - $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); - $this->debug('serializing return value'); - if($this->wsdl){ - // weak attempt at supporting multiple output params - if(sizeof($this->opData['output']['parts']) > 1){ - $opParams = $this->methodreturn; - } else { - // TODO: is this really necessary? - $opParams = array($this->methodreturn); - } - $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - if($errstr = $this->wsdl->getError()){ - $this->debug('got wsdl error: '.$errstr); - $this->fault('Server', 'unable to serialize result'); - return; - } - } else { - if (isset($this->methodreturn)) { - $return_val = $this->serialize_val($this->methodreturn, 'return'); - } else { - $return_val = ''; - $this->debug('in absence of WSDL, assume void return for backward compatibility'); - } - } - } - $this->debug('return value:'); - $this->appendDebug($this->varDump($return_val)); - - $this->debug('serializing response'); - if ($this->wsdl) { - $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); - if ($this->opData['style'] == 'rpc') { - $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); - if ($this->opData['output']['use'] == 'literal') { - $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>"; - } else { - $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; - } - } else { - $this->debug('style is not rpc for serialization: assume document'); - $payload = $return_val; - } - } else { - $this->debug('do not have WSDL for serialization: assume rpc/encoded'); - $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; - } - $this->result = 'successful'; - if($this->wsdl){ - //if($this->debug_flag){ - $this->appendDebug($this->wsdl->getDebug()); - // } - if (isset($opData['output']['encodingStyle'])) { - $encodingStyle = $opData['output']['encodingStyle']; - } else { - $encodingStyle = ''; - } - // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. - $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); - } else { - $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); - } - $this->debug("Leaving serialize_return"); - } - - /** - * sends an HTTP response - * - * The following fields are set by this function (when successful) - * - * outgoing_headers - * response - * - * @access private - */ - function send_response() { - $this->debug('Enter send_response'); - if ($this->fault) { - $payload = $this->fault->serialize(); - $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; - $this->outgoing_headers[] = "Status: 500 Internal Server Error"; - } else { - $payload = $this->responseSOAP; - // Some combinations of PHP+Web server allow the Status - // to come through as a header. Since OK is the default - // just do nothing. - // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; - // $this->outgoing_headers[] = "Status: 200 OK"; - } - // add debug data if in debug mode - if(isset($this->debug_flag) && $this->debug_flag){ - $payload .= $this->getDebugAsXMLComment(); - } - $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; - ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); - $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; - // Let the Web server decide about this - //$this->outgoing_headers[] = "Connection: Close\r\n"; - $payload = $this->getHTTPBody($payload); - $type = $this->getHTTPContentType(); - $charset = $this->getHTTPContentTypeCharset(); - $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); - //begin code to compress payload - by John - // NOTE: there is no way to know whether the Web server will also compress - // this data. - if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { - if (strstr($this->headers['accept-encoding'], 'gzip')) { - if (function_exists('gzencode')) { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content being gzipped -->"; - } - $this->outgoing_headers[] = "Content-Encoding: gzip"; - $payload = gzencode($payload); - } else { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content will not be gzipped: no gzencode -->"; - } - } - } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { - // Note: MSIE requires gzdeflate output (no Zlib header and checksum), - // instead of gzcompress output, - // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) - if (function_exists('gzdeflate')) { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content being deflated -->"; - } - $this->outgoing_headers[] = "Content-Encoding: deflate"; - $payload = gzdeflate($payload); - } else { - if (isset($this->debug_flag) && $this->debug_flag) { - $payload .= "<!-- Content will not be deflated: no gzcompress -->"; - } - } - } - } - //end code - $this->outgoing_headers[] = "Content-Length: ".strlen($payload); - reset($this->outgoing_headers); - foreach($this->outgoing_headers as $hdr){ - header($hdr, false); - } - print $payload; - $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; - } - - /** - * takes the value that was created by parsing the request - * and compares to the method's signature, if available. - * - * @param string $operation The operation to be invoked - * @param array $request The array of parameter values - * @return boolean Whether the operation was found - * @access private - */ - function verify_method($operation,$request){ - if(isset($this->wsdl) && is_object($this->wsdl)){ - if($this->wsdl->getOperationData($operation)){ - return true; - } - } elseif(isset($this->operations[$operation])){ - return true; - } - return false; - } - - /** - * processes SOAP message received from client - * - * @param array $headers The HTTP headers - * @param string $data unprocessed request data from client - * @return mixed value of the message, decoded into a PHP type - * @access private - */ - function parseRequest($headers, $data) { - $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); - if (!strstr($headers['content-type'], 'text/xml')) { - $this->setError('Request not of type text/xml'); - return false; - } - if (strpos($headers['content-type'], '=')) { - $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); - $this->debug('Got response encoding: ' . $enc); - if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); - // parse response, get soap parser obj - $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8); - // parser debug - $this->debug("parser debug: \n".$parser->getDebug()); - // if fault occurred during message parsing - if($err = $parser->getError()){ - $this->result = 'fault: error in msg parsing: '.$err; - $this->fault('Client',"error in msg parsing:\n".$err); - // else successfully parsed request into soapval object - } else { - // get/set methodname - $this->methodURI = $parser->root_struct_namespace; - $this->methodname = $parser->root_struct_name; - $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); - $this->debug('calling parser->get_response()'); - $this->methodparams = $parser->get_response(); - // get SOAP headers - $this->requestHeaders = $parser->getHeaders(); - // add document for doclit support - $this->document = $parser->document; - } - } - - /** - * gets the HTTP body for the current response. - * - * @param string $soapmsg The SOAP payload - * @return string The HTTP body, which includes the SOAP payload - * @access private - */ - function getHTTPBody($soapmsg) { - return $soapmsg; - } - - /** - * gets the HTTP content type for the current response. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type for the current response. - * @access private - */ - function getHTTPContentType() { - return 'text/xml'; - } - - /** - * gets the HTTP content type charset for the current response. - * returns false for non-text content types. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type charset for the current response. - * @access private - */ - function getHTTPContentTypeCharset() { - return $this->soap_defencoding; - } - - /** - * add a method to the dispatch map (this has been replaced by the register method) - * - * @param string $methodname - * @param string $in array of input values - * @param string $out array of output values - * @access public - * @deprecated - */ - function add_to_map($methodname,$in,$out){ - $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); - } - - /** - * register a service function with the server - * - * @param string $name the name of the PHP function, class.method or class..method - * @param array $in assoc array of input values: key = param name, value = param type - * @param array $out assoc array of output values: key = param name, value = param type - * @param mixed $namespace the element namespace for the method or false - * @param mixed $soapaction the soapaction for the method or false - * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically - * @param mixed $use optional (encoded|literal) or false - * @param string $documentation optional Description to include in WSDL - * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) - * @access public - */ - function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ - global $HTTP_SERVER_VARS; - - if($this->externalWSDLURL){ - die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); - } - if (! $name) { - die('You must specify a name when you register an operation'); - } - if (!is_array($in)) { - die('You must provide an array for operation inputs'); - } - if (!is_array($out)) { - die('You must provide an array for operation outputs'); - } - if(false == $namespace) { - } - if(false == $soapaction) { - if (isset($_SERVER)) { - $SERVER_NAME = $_SERVER['SERVER_NAME']; - $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; - } elseif (isset($HTTP_SERVER_VARS)) { - $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; - $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; - } else { - $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); - } - $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; - } - if(false == $style) { - $style = "rpc"; - } - if(false == $use) { - $use = "encoded"; - } - if ($use == 'encoded' && $encodingStyle = '') { - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - } - - $this->operations[$name] = array( - 'name' => $name, - 'in' => $in, - 'out' => $out, - 'namespace' => $namespace, - 'soapaction' => $soapaction, - 'style' => $style); - if($this->wsdl){ - $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); - } - return true; - } - - /** - * Specify a fault to be returned to the client. - * This also acts as a flag to the server that a fault has occured. - * - * @param string $faultcode - * @param string $faultstring - * @param string $faultactor - * @param string $faultdetail - * @access public - */ - function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ - if ($faultdetail == '' && $this->debug_flag) { - $faultdetail = $this->getDebug(); - } - $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); - $this->fault->soap_defencoding = $this->soap_defencoding; - } - - /** - * Sets up wsdl object. - * Acts as a flag to enable internal WSDL generation - * - * @param string $serviceName, name of the service - * @param mixed $namespace optional 'tns' service namespace or false - * @param mixed $endpoint optional URL of service endpoint or false - * @param string $style optional (rpc|document) WSDL style (also specified by operation) - * @param string $transport optional SOAP transport - * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false - */ - function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) - { - global $HTTP_SERVER_VARS; - - if (isset($_SERVER)) { - $SERVER_NAME = $_SERVER['SERVER_NAME']; - $SERVER_PORT = $_SERVER['SERVER_PORT']; - $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; - $HTTPS = $_SERVER['HTTPS']; - } elseif (isset($HTTP_SERVER_VARS)) { - $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; - $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; - $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; - $HTTPS = $HTTP_SERVER_VARS['HTTPS']; - } else { - $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); - } - if ($SERVER_PORT == 80) { - $SERVER_PORT = ''; - } else { - $SERVER_PORT = ':' . $SERVER_PORT; - } - if(false == $namespace) { - $namespace = "http://$SERVER_NAME/soap/$serviceName"; - } - - if(false == $endpoint) { - if ($HTTPS == '1' || $HTTPS == 'on') { - $SCHEME = 'https'; - } else { - $SCHEME = 'http'; - } - $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; - } - - if(false == $schemaTargetNamespace) { - $schemaTargetNamespace = $namespace; - } - - $this->wsdl = new wsdl; - $this->wsdl->serviceName = $serviceName; - $this->wsdl->endpoint = $endpoint; - $this->wsdl->namespaces['tns'] = $namespace; - $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; - $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; - if ($schemaTargetNamespace != $namespace) { - $this->wsdl->namespaces['types'] = $schemaTargetNamespace; - } - $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); - $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; - $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); - $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); - $this->wsdl->bindings[$serviceName.'Binding'] = array( - 'name'=>$serviceName.'Binding', - 'style'=>$style, - 'transport'=>$transport, - 'portType'=>$serviceName.'PortType'); - $this->wsdl->ports[$serviceName.'Port'] = array( - 'binding'=>$serviceName.'Binding', - 'location'=>$endpoint, - 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); - } -} - - - -?><?php - - - -/** -* parses a WSDL file, allows access to it's data, other utility methods -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class wsdl extends nusoap_base { - // URL or filename of the root of this WSDL - var $wsdl; - // define internal arrays of bindings, ports, operations, messages, etc. - var $schemas = array(); - var $currentSchema; - var $message = array(); - var $complexTypes = array(); - var $messages = array(); - var $currentMessage; - var $currentOperation; - var $portTypes = array(); - var $currentPortType; - var $bindings = array(); - var $currentBinding; - var $ports = array(); - var $currentPort; - var $opData = array(); - var $status = ''; - var $documentation = false; - var $endpoint = ''; - // array of wsdl docs to import - var $import = array(); - // parser vars - var $parser; - var $position = 0; - var $depth = 0; - var $depth_array = array(); - // for getting wsdl - var $proxyhost = ''; - var $proxyport = ''; - var $proxyusername = ''; - var $proxypassword = ''; - var $timeout = 0; - var $response_timeout = 30; - - /** - * constructor - * - * @param string $wsdl WSDL document URL - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @param integer $timeout set the connection timeout - * @param integer $response_timeout set the response timeout - * @access public - */ - function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ - parent::nusoap_base(); - $this->wsdl = $wsdl; - $this->proxyhost = $proxyhost; - $this->proxyport = $proxyport; - $this->proxyusername = $proxyusername; - $this->proxypassword = $proxypassword; - $this->timeout = $timeout; - $this->response_timeout = $response_timeout; - - // parse wsdl file - if ($wsdl != "") { - $this->debug('initial wsdl URL: ' . $wsdl); - $this->parseWSDL($wsdl); - } - // imports - // TODO: handle imports more properly, grabbing them in-line and nesting them - $imported_urls = array(); - $imported = 1; - while ($imported > 0) { - $imported = 0; - // Schema imports - foreach ($this->schemas as $ns => $list) { - foreach ($list as $xs) { - $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! - foreach ($xs->imports as $ns2 => $list2) { - for ($ii = 0; $ii < count($list2); $ii++) { - if (! $list2[$ii]['loaded']) { - $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; - $url = $list2[$ii]['location']; - if ($url != '') { - $urlparts = parse_url($url); - if (!isset($urlparts['host'])) { - $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . - substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; - } - if (! in_array($url, $imported_urls)) { - $this->parseWSDL($url); - $imported++; - $imported_urls[] = $url; - } - } else { - $this->debug("Unexpected scenario: empty URL for unloaded import"); - } - } - } - } - } - } - // WSDL imports - $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! - foreach ($this->import as $ns => $list) { - for ($ii = 0; $ii < count($list); $ii++) { - if (! $list[$ii]['loaded']) { - $this->import[$ns][$ii]['loaded'] = true; - $url = $list[$ii]['location']; - if ($url != '') { - $urlparts = parse_url($url); - if (!isset($urlparts['host'])) { - $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . - substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; - } - if (! in_array($url, $imported_urls)) { - $this->parseWSDL($url); - $imported++; - $imported_urls[] = $url; - } - } else { - $this->debug("Unexpected scenario: empty URL for unloaded import"); - } - } - } - } - } - // add new data to operation data - foreach($this->bindings as $binding => $bindingData) { - if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { - foreach($bindingData['operations'] as $operation => $data) { - $this->debug('post-parse data gathering for ' . $operation); - $this->bindings[$binding]['operations'][$operation]['input'] = - isset($this->bindings[$binding]['operations'][$operation]['input']) ? - array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : - $this->portTypes[ $bindingData['portType'] ][$operation]['input']; - $this->bindings[$binding]['operations'][$operation]['output'] = - isset($this->bindings[$binding]['operations'][$operation]['output']) ? - array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : - $this->portTypes[ $bindingData['portType'] ][$operation]['output']; - if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ - $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; - } - if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ - $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; - } - if (isset($bindingData['style'])) { - $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; - } - $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; - $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; - $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; - } - } - } - } - - /** - * parses the wsdl document - * - * @param string $wsdl path or URL - * @access private - */ - function parseWSDL($wsdl = '') - { - if ($wsdl == '') { - $this->debug('no wsdl passed to parseWSDL()!!'); - $this->setError('no wsdl passed to parseWSDL()!!'); - return false; - } - - // parse $wsdl for url format - $wsdl_props = parse_url($wsdl); - - if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { - $this->debug('getting WSDL http(s) URL ' . $wsdl); - // get wsdl - $tr = new soap_transport_http($wsdl); - $tr->request_method = 'GET'; - $tr->useSOAPAction = false; - if($this->proxyhost && $this->proxyport){ - $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); - } - $tr->setEncoding('gzip, deflate'); - $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); - //$this->debug("WSDL request\n" . $tr->outgoing_payload); - //$this->debug("WSDL response\n" . $tr->incoming_payload); - $this->appendDebug($tr->getDebug()); - // catch errors - if($err = $tr->getError() ){ - $errstr = 'HTTP ERROR: '.$err; - $this->debug($errstr); - $this->setError($errstr); - unset($tr); - return false; - } - unset($tr); - $this->debug("got WSDL URL"); - } else { - // $wsdl is not http(s), so treat it as a file URL or plain file path - if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { - $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; - } else { - $path = $wsdl; - } - $this->debug('getting WSDL file ' . $path); - if ($fp = @fopen($path, 'r')) { - $wsdl_string = ''; - while ($data = fread($fp, 32768)) { - $wsdl_string .= $data; - } - fclose($fp); - } else { - $errstr = "Bad path to WSDL file $path"; - $this->debug($errstr); - $this->setError($errstr); - return false; - } - } - $this->debug('Parse WSDL'); - // end new code added - // Create an XML parser. - $this->parser = xml_parser_create(); - // Set the options for parsing the XML data. - // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); - xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); - // Set the object for the parser. - xml_set_object($this->parser, $this); - // Set the element handlers for the parser. - xml_set_element_handler($this->parser, 'start_element', 'end_element'); - xml_set_character_data_handler($this->parser, 'character_data'); - // Parse the XML file. - if (!xml_parse($this->parser, $wsdl_string, true)) { - // Display an error message. - $errstr = sprintf( - 'XML error parsing WSDL from %s on line %d: %s', - $wsdl, - xml_get_current_line_number($this->parser), - xml_error_string(xml_get_error_code($this->parser)) - ); - $this->debug($errstr); - $this->debug("XML payload:\n" . $wsdl_string); - $this->setError($errstr); - return false; - } - // free the parser - xml_parser_free($this->parser); - $this->debug('Parsing WSDL done'); - // catch wsdl parse errors - if($this->getError()){ - return false; - } - return true; - } - - /** - * start-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @param string $attrs associative array of attributes - * @access private - */ - function start_element($parser, $name, $attrs) - { - if ($this->status == 'schema') { - $this->currentSchema->schemaStartElement($parser, $name, $attrs); - $this->appendDebug($this->currentSchema->getDebug()); - $this->currentSchema->clearDebug(); - } elseif (ereg('schema$', $name)) { - $this->debug('Parsing WSDL schema'); - // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); - $this->status = 'schema'; - $this->currentSchema = new xmlschema('', '', $this->namespaces); - $this->currentSchema->schemaStartElement($parser, $name, $attrs); - $this->appendDebug($this->currentSchema->getDebug()); - $this->currentSchema->clearDebug(); - } else { - // position in the total number of elements, starting from 0 - $pos = $this->position++; - $depth = $this->depth++; - // set self as current value for this depth - $this->depth_array[$depth] = $pos; - $this->message[$pos] = array('cdata' => ''); - // process attributes - if (count($attrs) > 0) { - // register namespace declarations - foreach($attrs as $k => $v) { - if (ereg("^xmlns", $k)) { - if ($ns_prefix = substr(strrchr($k, ':'), 1)) { - $this->namespaces[$ns_prefix] = $v; - } else { - $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; - } - if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { - $this->XMLSchemaVersion = $v; - $this->namespaces['xsi'] = $v . '-instance'; - } - } - } - // expand each attribute prefix to its namespace - foreach($attrs as $k => $v) { - $k = strpos($k, ':') ? $this->expandQname($k) : $k; - if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { - $v = strpos($v, ':') ? $this->expandQname($v) : $v; - } - $eAttrs[$k] = $v; - } - $attrs = $eAttrs; - } else { - $attrs = array(); - } - // get element prefix, namespace and name - if (ereg(':', $name)) { - // get ns prefix - $prefix = substr($name, 0, strpos($name, ':')); - // get ns - $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; - // get unqualified name - $name = substr(strstr($name, ':'), 1); - } - // process attributes, expanding any prefixes to namespaces - // find status, register data - switch ($this->status) { - case 'message': - if ($name == 'part') { - if (isset($attrs['type'])) { - $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); - $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; - } - if (isset($attrs['element'])) { - $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); - $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; - } - } - break; - case 'portType': - switch ($name) { - case 'operation': - $this->currentPortOperation = $attrs['name']; - $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); - if (isset($attrs['parameterOrder'])) { - $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; - } - break; - case 'documentation': - $this->documentation = true; - break; - // merge input/output data - default: - $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; - $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; - break; - } - break; - case 'binding': - switch ($name) { - case 'binding': - // get ns prefix - if (isset($attrs['style'])) { - $this->bindings[$this->currentBinding]['prefix'] = $prefix; - } - $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); - break; - case 'header': - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; - break; - case 'operation': - if (isset($attrs['soapAction'])) { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; - } - if (isset($attrs['style'])) { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; - } - if (isset($attrs['name'])) { - $this->currentOperation = $attrs['name']; - $this->debug("current binding operation: $this->currentOperation"); - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; - } - break; - case 'input': - $this->opStatus = 'input'; - break; - case 'output': - $this->opStatus = 'output'; - break; - case 'body': - if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); - } else { - $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; - } - break; - } - break; - case 'service': - switch ($name) { - case 'port': - $this->currentPort = $attrs['name']; - $this->debug('current port: ' . $this->currentPort); - $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); - - break; - case 'address': - $this->ports[$this->currentPort]['location'] = $attrs['location']; - $this->ports[$this->currentPort]['bindingType'] = $namespace; - $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; - $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; - break; - } - break; - } - // set status - switch ($name) { - case 'import': - if (isset($attrs['location'])) { - $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); - $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); - } else { - $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); - if (! $this->getPrefixFromNamespace($attrs['namespace'])) { - $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; - } - $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); - } - break; - //wait for schema - //case 'types': - // $this->status = 'schema'; - // break; - case 'message': - $this->status = 'message'; - $this->messages[$attrs['name']] = array(); - $this->currentMessage = $attrs['name']; - break; - case 'portType': - $this->status = 'portType'; - $this->portTypes[$attrs['name']] = array(); - $this->currentPortType = $attrs['name']; - break; - case "binding": - if (isset($attrs['name'])) { - // get binding name - if (strpos($attrs['name'], ':')) { - $this->currentBinding = $this->getLocalPart($attrs['name']); - } else { - $this->currentBinding = $attrs['name']; - } - $this->status = 'binding'; - $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); - $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); - } - break; - case 'service': - $this->serviceName = $attrs['name']; - $this->status = 'service'; - $this->debug('current service: ' . $this->serviceName); - break; - case 'definitions': - foreach ($attrs as $name => $value) { - $this->wsdl_info[$name] = $value; - } - break; - } - } - } - - /** - * end-element handler - * - * @param string $parser XML parser object - * @param string $name element name - * @access private - */ - function end_element($parser, $name){ - // unset schema status - if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { - $this->status = ""; - $this->appendDebug($this->currentSchema->getDebug()); - $this->currentSchema->clearDebug(); - $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; - $this->debug('Parsing WSDL schema done'); - } - if ($this->status == 'schema') { - $this->currentSchema->schemaEndElement($parser, $name); - } else { - // bring depth down a notch - $this->depth--; - } - // end documentation - if ($this->documentation) { - //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. - //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; - $this->documentation = false; - } - } - - /** - * element content handler - * - * @param string $parser XML parser object - * @param string $data element content - * @access private - */ - function character_data($parser, $data) - { - $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; - if (isset($this->message[$pos]['cdata'])) { - $this->message[$pos]['cdata'] .= $data; - } - if ($this->documentation) { - $this->documentation .= $data; - } - } - - function getBindingData($binding) - { - if (is_array($this->bindings[$binding])) { - return $this->bindings[$binding]; - } - } - - /** - * returns an assoc array of operation names => operation data - * - * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) - * @return array - * @access public - */ - function getOperations($bindingType = 'soap') - { - $ops = array(); - if ($bindingType == 'soap') { - $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; - } - // loop thru ports - foreach($this->ports as $port => $portData) { - // binding type of port matches parameter - if ($portData['bindingType'] == $bindingType) { - //$this->debug("getOperations for port $port"); - //$this->debug("port data: " . $this->varDump($portData)); - //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); - // merge bindings - if (isset($this->bindings[ $portData['binding'] ]['operations'])) { - $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); - } - } - } - return $ops; - } - - /** - * returns an associative array of data necessary for calling an operation - * - * @param string $operation , name of operation - * @param string $bindingType , type of binding eg: soap - * @return array - * @access public - */ - function getOperationData($operation, $bindingType = 'soap') - { - if ($bindingType == 'soap') { - $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; - } - // loop thru ports - foreach($this->ports as $port => $portData) { - // binding type of port matches parameter - if ($portData['bindingType'] == $bindingType) { - // get binding - //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { - foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { - // note that we could/should also check the namespace here - if ($operation == $bOperation) { - $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; - return $opData; - } - } - } - } - } - - /** - * returns an associative array of data necessary for calling an operation - * - * @param string $soapAction soapAction for operation - * @param string $bindingType type of binding eg: soap - * @return array - * @access public - */ - function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { - if ($bindingType == 'soap') { - $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; - } - // loop thru ports - foreach($this->ports as $port => $portData) { - // binding type of port matches parameter - if ($portData['bindingType'] == $bindingType) { - // loop through operations for the binding - foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { - if ($opData['soapAction'] == $soapAction) { - return $opData; - } - } - } - } - } - - /** - * returns an array of information about a given type - * returns false if no type exists by the given name - * - * typeDef = array( - * 'elements' => array(), // refs to elements array - * 'restrictionBase' => '', - * 'phpType' => '', - * 'order' => '(sequence|all)', - * 'attrs' => array() // refs to attributes array - * ) - * - * @param $type string the type - * @param $ns string namespace (not prefix) of the type - * @return mixed - * @access public - * @see xmlschema - */ - function getTypeDef($type, $ns) { - $this->debug("in getTypeDef: type=$type, ns=$ns"); - if ((! $ns) && isset($this->namespaces['tns'])) { - $ns = $this->namespaces['tns']; - $this->debug("in getTypeDef: type namespace forced to $ns"); - } - if (isset($this->schemas[$ns])) { - $this->debug("in getTypeDef: have schema for namespace $ns"); - for ($i = 0; $i < count($this->schemas[$ns]); $i++) { - $xs = &$this->schemas[$ns][$i]; - $t = $xs->getTypeDef($type); - $this->appendDebug($xs->getDebug()); - $xs->clearDebug(); - if ($t) { - if (!isset($t['phpType'])) { - // get info for type to tack onto the element - $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); - $ns = substr($t['type'], 0, strrpos($t['type'], ':')); - $etype = $this->getTypeDef($uqType, $ns); - if ($etype) { - $this->debug("found type for [element] $type:"); - $this->debug($this->varDump($etype)); - if (isset($etype['phpType'])) { - $t['phpType'] = $etype['phpType']; - } - if (isset($etype['elements'])) { - $t['elements'] = $etype['elements']; - } - if (isset($etype['attrs'])) { - $t['attrs'] = $etype['attrs']; - } - } - } - return $t; - } - } - } else { - $this->debug("in getTypeDef: do not have schema for namespace $ns"); - } - return false; - } - - /** - * prints html description of services - * - * @access private - */ - function webDescription(){ - global $HTTP_SERVER_VARS; - - if (isset($_SERVER)) { - $PHP_SELF = $_SERVER['PHP_SELF']; - } elseif (isset($HTTP_SERVER_VARS)) { - $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; - } else { - $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); - } - - $b = ' - <html><head><title>NuSOAP: '.$this->serviceName.'</title> - <style type="text/css"> - body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } - p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } - pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} - ul { margin-top: 10px; margin-left: 20px; } - li { list-style-type: none; margin-top: 10px; color: #000000; } - .content{ - margin-left: 0px; padding-bottom: 2em; } - .nav { - padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; - margin-top: 10px; margin-left: 0px; color: #000000; - background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } - .title { - font-family: arial; font-size: 26px; color: #ffffff; - background-color: #999999; width: 105%; margin-left: 0px; - padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} - .hidden { - position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; - font-family: arial; overflow: hidden; width: 600; - padding: 20px; font-size: 10px; background-color: #999999; - layer-background-color:#FFFFFF; } - a,a:active { color: charcoal; font-weight: bold; } - a:visited { color: #666666; font-weight: bold; } - a:hover { color: cc3300; font-weight: bold; } - </style> - <script language="JavaScript" type="text/javascript"> - <!-- - // POP-UP CAPTIONS... - function lib_bwcheck(){ //Browsercheck (needed) - this.ver=navigator.appVersion - this.agent=navigator.userAgent - this.dom=document.getElementById?1:0 - this.opera5=this.agent.indexOf("Opera 5")>-1 - this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; - this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; - this.ie4=(document.all && !this.dom && !this.opera5)?1:0; - this.ie=this.ie4||this.ie5||this.ie6 - this.mac=this.agent.indexOf("Mac")>-1 - this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; - this.ns4=(document.layers && !this.dom)?1:0; - this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) - return this - } - var bw = new lib_bwcheck() - //Makes crossbrowser object. - function makeObj(obj){ - this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; - if(!this.evnt) return false - this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; - this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; - this.writeIt=b_writeIt; - return this - } - // A unit of measure that will be added when setting the position of a layer. - //var px = bw.ns4||window.opera?"":"px"; - function b_writeIt(text){ - if (bw.ns4){this.wref.write(text);this.wref.close()} - else this.wref.innerHTML = text - } - //Shows the messages - var oDesc; - function popup(divid){ - if(oDesc = new makeObj(divid)){ - oDesc.css.visibility = "visible" - } - } - function popout(){ // Hides message - if(oDesc) oDesc.css.visibility = "hidden" - } - //--> - </script> - </head> - <body> - <div class=content> - <br><br> - <div class=title>'.$this->serviceName.'</div> - <div class=nav> - <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service. - Click on an operation name to view it's details.</p> - <ul>'; - foreach($this->getOperations() as $op => $data){ - $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>"; - // create hidden div - $b .= "<div id='$op' class='hidden'> - <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>"; - foreach($data as $donnie => $marie){ // loop through opdata - if($donnie == 'input' || $donnie == 'output'){ // show input/output data - $b .= "<font color='white'>".ucfirst($donnie).':</font><br>'; - foreach($marie as $captain => $tenille){ // loop through data - if($captain == 'parts'){ // loop thru parts - $b .= " $captain:<br>"; - //if(is_array($tenille)){ - foreach($tenille as $joanie => $chachi){ - $b .= " $joanie: $chachi<br>"; - } - //} - } else { - $b .= " $captain: $tenille<br>"; - } - } - } else { - $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>"; - } - } - $b .= '</div>'; - } - $b .= ' - <ul> - </div> - </div></body></html>'; - return $b; - } - - /** - * serialize the parsed wsdl - * - * @param mixed $debug whether to put debug=1 in endpoint URL - * @return string serialization of WSDL - * @access public - */ - function serialize($debug = 0) - { - $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'; - $xml .= "\n<definitions"; - foreach($this->namespaces as $k => $v) { - $xml .= " xmlns:$k=\"$v\""; - } - // 10.9.02 - add poulter fix for wsdl and tns declarations - if (isset($this->namespaces['wsdl'])) { - $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; - } - if (isset($this->namespaces['tns'])) { - $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; - } - $xml .= '>'; - // imports - if (sizeof($this->import) > 0) { - foreach($this->import as $ns => $list) { - foreach ($list as $ii) { - if ($ii['location'] != '') { - $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />'; - } else { - $xml .= '<import namespace="' . $ns . '" />'; - } - } - } - } - // types - if (count($this->schemas)>=1) { - $xml .= "\n<types>"; - foreach ($this->schemas as $ns => $list) { - foreach ($list as $xs) { - $xml .= $xs->serializeSchema(); - } - } - $xml .= '</types>'; - } - // messages - if (count($this->messages) >= 1) { - foreach($this->messages as $msgName => $msgParts) { - $xml .= "\n<message name=\"" . $msgName . '">'; - if(is_array($msgParts)){ - foreach($msgParts as $partName => $partType) { - // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>'; - if (strpos($partType, ':')) { - $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); - } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { - // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>'; - $typePrefix = 'xsd'; - } else { - foreach($this->typemap as $ns => $types) { - if (isset($types[$partType])) { - $typePrefix = $this->getPrefixFromNamespace($ns); - } - } - if (!isset($typePrefix)) { - die("$partType has no namespace!"); - } - } - $ns = $this->getNamespaceFromPrefix($typePrefix); - $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); - if ($typeDef['typeClass'] == 'element') { - $elementortype = 'element'; - } else { - $elementortype = 'type'; - } - $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />'; - } - } - $xml .= '</message>'; - } - } - // bindings & porttypes - if (count($this->bindings) >= 1) { - $binding_xml = ''; - $portType_xml = ''; - foreach($this->bindings as $bindingName => $attrs) { - $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">'; - $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>'; - $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">'; - foreach($attrs['operations'] as $opName => $opParts) { - $binding_xml .= '<operation name="' . $opName . '">'; - $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>'; - if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { - $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; - } else { - $enc_style = ''; - } - $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>'; - if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { - $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; - } else { - $enc_style = ''; - } - $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>'; - $binding_xml .= '</operation>'; - $portType_xml .= '<operation name="' . $opParts['name'] . '"'; - if (isset($opParts['parameterOrder'])) { - $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"'; - } - $portType_xml .= '>'; - if(isset($opParts['documentation']) && $opParts['documentation'] != '') { - $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>'; - } - $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>'; - $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>'; - $portType_xml .= '</operation>'; - } - $portType_xml .= '</portType>'; - $binding_xml .= '</binding>'; - } - $xml .= $portType_xml . $binding_xml; - } - // services - $xml .= "\n<service name=\"" . $this->serviceName . '">'; - if (count($this->ports) >= 1) { - foreach($this->ports as $pName => $attrs) { - $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">'; - $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>'; - $xml .= '</port>'; - } - } - $xml .= '</service>'; - return $xml . "\n</definitions>"; - } - - /** - * serialize PHP values according to a WSDL message definition - * - * TODO - * - multi-ref serialization - * - validate PHP values against type definitions, return errors if invalid - * - * @param string $operation operation name - * @param string $direction (input|output) - * @param mixed $parameters parameter value(s) - * @return mixed parameters serialized as XML or false on error (e.g. operation not found) - * @access public - */ - function serializeRPCParameters($operation, $direction, $parameters) - { - $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); - $this->appendDebug('parameters=' . $this->varDump($parameters)); - - if ($direction != 'input' && $direction != 'output') { - $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); - $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); - return false; - } - if (!$opData = $this->getOperationData($operation)) { - $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); - $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); - return false; - } - $this->debug('opData:'); - $this->appendDebug($this->varDump($opData)); - - // Get encoding style for output and set to current - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { - $encodingStyle = $opData['output']['encodingStyle']; - $enc_style = $encodingStyle; - } - - // set input params - $xml = ''; - if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { - - $use = $opData[$direction]['use']; - $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); - if (is_array($parameters)) { - $parametersArrayType = $this->isArraySimpleOrStruct($parameters); - $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); - foreach($opData[$direction]['parts'] as $name => $type) { - $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); - // Track encoding style - if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { - $encodingStyle = $opData[$direction]['encodingStyle']; - $enc_style = $encodingStyle; - } else { - $enc_style = false; - } - // NOTE: add error handling here - // if serializeType returns false, then catch global error and fault - if ($parametersArrayType == 'arraySimple') { - $p = array_shift($parameters); - $this->debug('calling serializeType w/indexed param'); - $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); - } elseif (isset($parameters[$name])) { - $this->debug('calling serializeType w/named param'); - $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); - } else { - // TODO: only send nillable - $this->debug('calling serializeType w/null param'); - $xml .= $this->serializeType($name, $type, null, $use, $enc_style); - } - } - } else { - $this->debug('no parameters passed.'); - } - } - $this->debug("serializeRPCParameters returning: $xml"); - return $xml; - } - - /** - * serialize a PHP value according to a WSDL message definition - * - * TODO - * - multi-ref serialization - * - validate PHP values against type definitions, return errors if invalid - * - * @param string $ type name - * @param mixed $ param value - * @return mixed new param or false if initial value didn't validate - * @access public - * @deprecated - */ - function serializeParameters($operation, $direction, $parameters) - { - $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); - $this->appendDebug('parameters=' . $this->varDump($parameters)); - - if ($direction != 'input' && $direction != 'output') { - $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); - $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); - return false; - } - if (!$opData = $this->getOperationData($operation)) { - $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); - $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); - return false; - } - $this->debug('opData:'); - $this->appendDebug($this->varDump($opData)); - - // Get encoding style for output and set to current - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { - $encodingStyle = $opData['output']['encodingStyle']; - $enc_style = $encodingStyle; - } - - // set input params - $xml = ''; - if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { - - $use = $opData[$direction]['use']; - $this->debug("use=$use"); - $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); - if (is_array($parameters)) { - $parametersArrayType = $this->isArraySimpleOrStruct($parameters); - $this->debug('have ' . $parametersArrayType . ' parameters'); - foreach($opData[$direction]['parts'] as $name => $type) { - $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); - // Track encoding style - if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { - $encodingStyle = $opData[$direction]['encodingStyle']; - $enc_style = $encodingStyle; - } else { - $enc_style = false; - } - // NOTE: add error handling here - // if serializeType returns false, then catch global error and fault - if ($parametersArrayType == 'arraySimple') { - $p = array_shift($parameters); - $this->debug('calling serializeType w/indexed param'); - $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); - } elseif (isset($parameters[$name])) { - $this->debug('calling serializeType w/named param'); - $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); - } else { - // TODO: only send nillable - $this->debug('calling serializeType w/null param'); - $xml .= $this->serializeType($name, $type, null, $use, $enc_style); - } - } - } else { - $this->debug('no parameters passed.'); - } - } - $this->debug("serializeParameters returning: $xml"); - return $xml; - } - - /** - * serializes a PHP value according a given type definition - * - * @param string $name name of value (part or element) - * @param string $type XML schema type of value (type or element) - * @param mixed $value a native PHP value (parameter value) - * @param string $use use for part (encoded|literal) - * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) - * @param boolean $unqualified a kludge for what should be XML namespace form handling - * @return string value serialized as an XML string - * @access private - */ - function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) - { - $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); - $this->appendDebug("value=" . $this->varDump($value)); - if($use == 'encoded' && $encodingStyle) { - $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; - } - - // if a soapval has been supplied, let its type override the WSDL - if (is_object($value) && get_class($value) == 'soapval') { - if ($value->type_ns) { - $type = $value->type_ns . ':' . $value->type; - $forceType = true; - $this->debug("in serializeType: soapval overrides type to $type"); - } elseif ($value->type) { - $type = $value->type; - $forceType = true; - $this->debug("in serializeType: soapval overrides type to $type"); - } else { - $forceType = false; - $this->debug("in serializeType: soapval does not override type"); - } - $attrs = $value->attributes; - $value = $value->value; - $this->debug("in serializeType: soapval overrides value to $value"); - if ($attrs) { - if (!is_array($value)) { - $value['!'] = $value; - } - foreach ($attrs as $n => $v) { - $value['!' . $n] = $v; - } - $this->debug("in serializeType: soapval provides attributes"); - } - } else { - $forceType = false; - } - - $xml = ''; - if (strpos($type, ':')) { - $uqType = substr($type, strrpos($type, ':') + 1); - $ns = substr($type, 0, strrpos($type, ':')); - $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); - if ($this->getNamespaceFromPrefix($ns)) { - $ns = $this->getNamespaceFromPrefix($ns); - $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); - } - - if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ - $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); - if ($unqualified && $use == 'literal') { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - if (is_null($value)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - $xml = "<$name$elementNS/>"; - } else { - // TODO: depends on nillable, which should be checked before calling this method - $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - if ($uqType == 'boolean') { - if ((is_string($value) && $value == 'false') || (! $value)) { - $value = 'false'; - } else { - $value = 'true'; - } - } - if ($uqType == 'string' && gettype($value) == 'string') { - $value = $this->expandEntities($value); - } - if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { - $value = sprintf("%.0lf", $value); - } - // it's a scalar - // TODO: what about null/nil values? - // check type isn't a custom type extending xmlschema namespace - if (!$this->getTypeDef($uqType, $ns)) { - if ($use == 'literal') { - if ($forceType) { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; - } else { - $xml = "<$name$elementNS>$value</$name>"; - } - } else { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); - } else if ($ns == 'http://xml.apache.org/xml-soap') { - $this->debug('in serializeType: appears to be Apache SOAP type'); - if ($uqType == 'Map') { - $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); - if (! $tt_prefix) { - $this->debug('in serializeType: Add namespace for Apache SOAP type'); - $tt_prefix = 'ns' . rand(1000, 9999); - $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; - // force this to be added to usedNamespaces - $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); - } - $contents = ''; - foreach($value as $k => $v) { - $this->debug("serializing map element: key $k, value $v"); - $contents .= '<item>'; - $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); - $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); - $contents .= '</item>'; - } - if ($use == 'literal') { - if ($forceType) { - $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>"; - } else { - $xml = "<$name>$contents</$name>"; - } - } else { - $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - $this->debug('in serializeType: Apache SOAP type, but only support Map'); - } - } else { - // TODO: should the type be compared to types in XSD, and the namespace - // set to XSD if the type matches? - $this->debug("in serializeType: No namespace for type $type"); - $ns = ''; - $uqType = $type; - } - if(!$typeDef = $this->getTypeDef($uqType, $ns)){ - $this->setError("$type ($uqType) is not a supported type."); - $this->debug("in serializeType: $type ($uqType) is not a supported type."); - return false; - } else { - $this->debug("in serializeType: found typeDef"); - $this->appendDebug('typeDef=' . $this->varDump($typeDef)); - } - $phpType = $typeDef['phpType']; - $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); - // if php type == struct, map value to the <all> element names - if ($phpType == 'struct') { - if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { - $elementName = $uqType; - if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { - $elementNS = " xmlns=\"$ns\""; - } else { - $elementNS = " xmlns=\"\""; - } - } else { - $elementName = $name; - if ($unqualified) { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - } - if (is_null($value)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - $xml = "<$elementName$elementNS/>"; - } else { - $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - if (is_object($value)) { - $value = get_object_vars($value); - } - if (is_array($value)) { - $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); - if ($use == 'literal') { - if ($forceType) { - $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; - } else { - $xml = "<$elementName$elementNS$elementAttrs>"; - } - } else { - $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; - } - - $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); - $xml .= "</$elementName>"; - } else { - $this->debug("in serializeType: phpType is struct, but value is not an array"); - $this->setError("phpType is struct, but value is not an array: see debug output for details"); - $xml = ''; - } - } elseif ($phpType == 'array') { - if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { - $elementNS = " xmlns=\"$ns\""; - } else { - if ($unqualified) { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - } - if (is_null($value)) { - if ($use == 'literal') { - // TODO: depends on minOccurs - $xml = "<$name$elementNS/>"; - } else { - $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . - $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . - ":Array\" " . - $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . - ':arrayType="' . - $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . - ':' . - $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - if (isset($typeDef['multidimensional'])) { - $nv = array(); - foreach($value as $v) { - $cols = ',' . sizeof($v); - $nv = array_merge($nv, $v); - } - $value = $nv; - } else { - $cols = ''; - } - if (is_array($value) && sizeof($value) >= 1) { - $rows = sizeof($value); - $contents = ''; - foreach($value as $k => $v) { - $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); - //if (strpos($typeDef['arrayType'], ':') ) { - if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { - $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); - } else { - $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); - } - } - } else { - $rows = 0; - $contents = null; - } - // TODO: for now, an empty value will be serialized as a zero element - // array. Revisit this when coding the handling of null/nil values. - if ($use == 'literal') { - $xml = "<$name$elementNS>" - .$contents - ."</$name>"; - } else { - $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. - $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') - .':arrayType="' - .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) - .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" - .$contents - ."</$name>"; - } - } elseif ($phpType == 'scalar') { - if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { - $elementNS = " xmlns=\"$ns\""; - } else { - if ($unqualified) { - $elementNS = " xmlns=\"\""; - } else { - $elementNS = ''; - } - } - if ($use == 'literal') { - if ($forceType) { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; - } else { - $xml = "<$name$elementNS>$value</$name>"; - } - } else { - $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; - } - } - $this->debug("in serializeType: returning: $xml"); - return $xml; - } - - /** - * serializes the attributes for a complexType - * - * @param array $typeDef our internal representation of an XML schema type (or element) - * @param mixed $value a native PHP value (parameter value) - * @param string $ns the namespace of the type - * @param string $uqType the local part of the type - * @return string value serialized as an XML string - * @access private - */ - function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { - $xml = ''; - if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { - $this->debug("serialize attributes for XML Schema type $ns:$uqType"); - if (is_array($value)) { - $xvalue = $value; - } elseif (is_object($value)) { - $xvalue = get_object_vars($value); - } else { - $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); - $xvalue = array(); - } - foreach ($typeDef['attrs'] as $aName => $attrs) { - if (isset($xvalue['!' . $aName])) { - $xname = '!' . $aName; - $this->debug("value provided for attribute $aName with key $xname"); - } elseif (isset($xvalue[$aName])) { - $xname = $aName; - $this->debug("value provided for attribute $aName with key $xname"); - } elseif (isset($attrs['default'])) { - $xname = '!' . $aName; - $xvalue[$xname] = $attrs['default']; - $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); - } else { - $xname = ''; - $this->debug("no value provided for attribute $aName"); - } - if ($xname) { - $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; - } - } - } else { - $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); - } - if (isset($typeDef['extensionBase'])) { - $ns = $this->getPrefix($typeDef['extensionBase']); - $uqType = $this->getLocalPart($typeDef['extensionBase']); - if ($this->getNamespaceFromPrefix($ns)) { - $ns = $this->getNamespaceFromPrefix($ns); - } - if ($typeDef = $this->getTypeDef($uqType, $ns)) { - $this->debug("serialize attributes for extension base $ns:$uqType"); - $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); - } else { - $this->debug("extension base $ns:$uqType is not a supported type"); - } - } - return $xml; - } - - /** - * serializes the elements for a complexType - * - * @param array $typeDef our internal representation of an XML schema type (or element) - * @param mixed $value a native PHP value (parameter value) - * @param string $ns the namespace of the type - * @param string $uqType the local part of the type - * @param string $use use for part (encoded|literal) - * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) - * @return string value serialized as an XML string - * @access private - */ - function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { - $xml = ''; - if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { - $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); - if (is_array($value)) { - $xvalue = $value; - } elseif (is_object($value)) { - $xvalue = get_object_vars($value); - } else { - $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); - $xvalue = array(); - } - // toggle whether all elements are present - ideally should validate against schema - if (count($typeDef['elements']) != count($xvalue)){ - $optionals = true; - } - foreach ($typeDef['elements'] as $eName => $attrs) { - if (!isset($xvalue[$eName])) { - if (isset($attrs['default'])) { - $xvalue[$eName] = $attrs['default']; - $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); - } - } - // if user took advantage of a minOccurs=0, then only serialize named parameters - if (isset($optionals) - && (!isset($xvalue[$eName])) - && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') - ){ - if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { - $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); - } - // do nothing - $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); - } else { - // get value - if (isset($xvalue[$eName])) { - $v = $xvalue[$eName]; - } else { - $v = null; - } - if (isset($attrs['form'])) { - $unqualified = ($attrs['form'] == 'unqualified'); - } else { - $unqualified = false; - } - if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { - $vv = $v; - foreach ($vv as $k => $v) { - if (isset($attrs['type']) || isset($attrs['ref'])) { - // serialize schema-defined type - $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); - } else { - // serialize generic type (can this ever really happen?) - $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); - $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); - } - } - } else { - if (isset($attrs['type']) || isset($attrs['ref'])) { - // serialize schema-defined type - $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); - } else { - // serialize generic type (can this ever really happen?) - $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); - $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); - } - } - } - } - } else { - $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); - } - if (isset($typeDef['extensionBase'])) { - $ns = $this->getPrefix($typeDef['extensionBase']); - $uqType = $this->getLocalPart($typeDef['extensionBase']); - if ($this->getNamespaceFromPrefix($ns)) { - $ns = $this->getNamespaceFromPrefix($ns); - } - if ($typeDef = $this->getTypeDef($uqType, $ns)) { - $this->debug("serialize elements for extension base $ns:$uqType"); - $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); - } else { - $this->debug("extension base $ns:$uqType is not a supported type"); - } - } - return $xml; - } - - /** - * adds an XML Schema complex type to the WSDL types - * - * @param string name - * @param string typeClass (complexType|simpleType|attribute) - * @param string phpType: currently supported are array and struct (php assoc array) - * @param string compositor (all|sequence|choice) - * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param array elements = array ( name => array(name=>'',type=>'') ) - * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) - * @param string arrayType: namespace:name (xsd:string) - * @see xmlschema - * @access public - */ - function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { - if (count($elements) > 0) { - foreach($elements as $n => $e){ - // expand each element - foreach ($e as $k => $v) { - $k = strpos($k,':') ? $this->expandQname($k) : $k; - $v = strpos($v,':') ? $this->expandQname($v) : $v; - $ee[$k] = $v; - } - $eElements[$n] = $ee; - } - $elements = $eElements; - } - - if (count($attrs) > 0) { - foreach($attrs as $n => $a){ - // expand each attribute - foreach ($a as $k => $v) { - $k = strpos($k,':') ? $this->expandQname($k) : $k; - $v = strpos($v,':') ? $this->expandQname($v) : $v; - $aa[$k] = $v; - } - $eAttrs[$n] = $aa; - } - $attrs = $eAttrs; - } - - $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; - $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; - - $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; - $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); - } - - /** - * adds an XML Schema simple type to the WSDL types - * - * @param string $name - * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) - * @param string $typeClass (should always be simpleType) - * @param string $phpType (should always be scalar) - * @param array $enumeration array of values - * @see xmlschema - * @access public - */ - function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { - $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; - - $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; - $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); - } - - /** - * adds an element to the WSDL types - * - * @param array $attrs attributes that must include name and type - * @see xmlschema - * @access public - */ - function addElement($attrs) { - $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; - $this->schemas[$typens][0]->addElement($attrs); - } - - /** - * register an operation with the server - * - * @param string $name operation (method) name - * @param array $in assoc array of input values: key = param name, value = param type - * @param array $out assoc array of output values: key = param name, value = param type - * @param string $namespace optional The namespace for the operation - * @param string $soapaction optional The soapaction for the operation - * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically - * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) - * @param string $documentation optional The description to include in the WSDL - * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) - * @access public - */ - function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ - if ($use == 'encoded' && $encodingStyle == '') { - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - } - - if ($style == 'document') { - $elements = array(); - foreach ($in as $n => $t) { - $elements[$n] = array('name' => $n, 'type' => $t); - } - $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); - $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); - $in = array('parameters' => 'tns:' . $name); - - $elements = array(); - foreach ($out as $n => $t) { - $elements[$n] = array('name' => $n, 'type' => $t); - } - $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); - $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); - $out = array('parameters' => 'tns:' . $name . 'Response'); - } - - // get binding - $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = - array( - 'name' => $name, - 'binding' => $this->serviceName . 'Binding', - 'endpoint' => $this->endpoint, - 'soapAction' => $soapaction, - 'style' => $style, - 'input' => array( - 'use' => $use, - 'namespace' => $namespace, - 'encodingStyle' => $encodingStyle, - 'message' => $name . 'Request', - 'parts' => $in), - 'output' => array( - 'use' => $use, - 'namespace' => $namespace, - 'encodingStyle' => $encodingStyle, - 'message' => $name . 'Response', - 'parts' => $out), - 'namespace' => $namespace, - 'transport' => 'http://schemas.xmlsoap.org/soap/http', - 'documentation' => $documentation); - // add portTypes - // add messages - if($in) - { - foreach($in as $pName => $pType) - { - if(strpos($pType,':')) { - $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); - } - $this->messages[$name.'Request'][$pName] = $pType; - } - } else { - $this->messages[$name.'Request']= '0'; - } - if($out) - { - foreach($out as $pName => $pType) - { - if(strpos($pType,':')) { - $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); - } - $this->messages[$name.'Response'][$pName] = $pType; - } - } else { - $this->messages[$name.'Response']= '0'; - } - return true; - } -} -?><?php - - - -/** -* -* soap_parser class parses SOAP XML messages into native PHP values -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soap_parser extends nusoap_base { - - var $xml = ''; - var $xml_encoding = ''; - var $method = ''; - var $root_struct = ''; - var $root_struct_name = ''; - var $root_struct_namespace = ''; - var $root_header = ''; - var $document = ''; // incoming SOAP body (text) - // determines where in the message we are (envelope,header,body,method) - var $status = ''; - var $position = 0; - var $depth = 0; - var $default_namespace = ''; - var $namespaces = array(); - var $message = array(); - var $parent = ''; - var $fault = false; - var $fault_code = ''; - var $fault_str = ''; - var $fault_detail = ''; - var $depth_array = array(); - var $debug_flag = true; - var $soapresponse = NULL; - var $responseHeaders = ''; // incoming SOAP headers (text) - var $body_position = 0; - // for multiref parsing: - // array of id => pos - var $ids = array(); - // array of id => hrefs => pos - var $multirefs = array(); - // toggle for auto-decoding element content - var $decode_utf8 = true; - - /** - * constructor that actually does the parsing - * - * @param string $xml SOAP message - * @param string $encoding character encoding scheme of message - * @param string $method method for which XML is parsed (unused?) - * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 - * @access public - */ - function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ - parent::nusoap_base(); - $this->xml = $xml; - $this->xml_encoding = $encoding; - $this->method = $method; - $this->decode_utf8 = $decode_utf8; - - // Check whether content has been read. - if(!empty($xml)){ - // Check XML encoding - $pos_xml = strpos($xml, '<?xml'); - if ($pos_xml !== FALSE) { - $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1); - if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { - $xml_encoding = $res[1]; - if (strtoupper($xml_encoding) != $encoding) { - $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; - $this->debug($err); - if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { - $this->setError($err); - return; - } - // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed - } else { - $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); - } - } else { - $this->debug('No encoding specified in XML declaration'); - } - } else { - $this->debug('No XML declaration'); - } - $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); - // Create an XML parser - why not xml_parser_create_ns? - $this->parser = xml_parser_create($this->xml_encoding); - // Set the options for parsing the XML data. - //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); - xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); - xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); - // Set the object for the parser. - xml_set_object($this->parser, $this); - // Set the element handlers for the parser. - xml_set_element_handler($this->parser, 'start_element','end_element'); - xml_set_character_data_handler($this->parser,'character_data'); - - // Parse the XML file. - if(!xml_parse($this->parser,$xml,true)){ - // Display an error message. - $err = sprintf('XML error parsing SOAP payload on line %d: %s', - xml_get_current_line_number($this->parser), - xml_error_string(xml_get_error_code($this->parser))); - $this->debug($err); - $this->debug("XML payload:\n" . $xml); - $this->setError($err); - } else { - $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); - // get final value - $this->soapresponse = $this->message[$this->root_struct]['result']; - // get header value: no, because this is documented as XML string -// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ -// $this->responseHeaders = $this->message[$this->root_header]['result']; -// } - // resolve hrefs/ids - if(sizeof($this->multirefs) > 0){ - foreach($this->multirefs as $id => $hrefs){ - $this->debug('resolving multirefs for id: '.$id); - $idVal = $this->buildVal($this->ids[$id]); - if (is_array($idVal) && isset($idVal['!id'])) { - unset($idVal['!id']); - } - foreach($hrefs as $refPos => $ref){ - $this->debug('resolving href at pos '.$refPos); - $this->multirefs[$id][$refPos] = $idVal; - } - } - } - } - xml_parser_free($this->parser); - } else { - $this->debug('xml was empty, didn\'t parse!'); - $this->setError('xml was empty, didn\'t parse!'); - } - } - - /** - * start-element handler - * - * @param resource $parser XML parser object - * @param string $name element name - * @param array $attrs associative array of attributes - * @access private - */ - function start_element($parser, $name, $attrs) { - // position in a total number of elements, starting from 0 - // update class level pos - $pos = $this->position++; - // and set mine - $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); - // depth = how many levels removed from root? - // set mine as current global depth and increment global depth value - $this->message[$pos]['depth'] = $this->depth++; - - // else add self as child to whoever the current parent is - if($pos != 0){ - $this->message[$this->parent]['children'] .= '|'.$pos; - } - // set my parent - $this->message[$pos]['parent'] = $this->parent; - // set self as current parent - $this->parent = $pos; - // set self as current value for this depth - $this->depth_array[$this->depth] = $pos; - // get element prefix - if(strpos($name,':')){ - // get ns prefix - $prefix = substr($name,0,strpos($name,':')); - // get unqualified name - $name = substr(strstr($name,':'),1); - } - // set status - if($name == 'Envelope'){ - $this->status = 'envelope'; - } elseif($name == 'Header'){ - $this->root_header = $pos; - $this->status = 'header'; - } elseif($name == 'Body'){ - $this->status = 'body'; - $this->body_position = $pos; - // set method - } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ - $this->status = 'method'; - $this->root_struct_name = $name; - $this->root_struct = $pos; - $this->message[$pos]['type'] = 'struct'; - $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); - } - // set my status - $this->message[$pos]['status'] = $this->status; - // set name - $this->message[$pos]['name'] = htmlspecialchars($name); - // set attrs - $this->message[$pos]['attrs'] = $attrs; - - // loop through atts, logging ns and type declarations - $attstr = ''; - foreach($attrs as $key => $value){ - $key_prefix = $this->getPrefix($key); - $key_localpart = $this->getLocalPart($key); - // if ns declarations, add to class level array of valid namespaces - if($key_prefix == 'xmlns'){ - if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ - $this->XMLSchemaVersion = $value; - $this->namespaces['xsd'] = $this->XMLSchemaVersion; - $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; - } - $this->namespaces[$key_localpart] = $value; - // set method namespace - if($name == $this->root_struct_name){ - $this->methodNamespace = $value; - } - // if it's a type declaration, set type - } elseif($key_localpart == 'type'){ - $value_prefix = $this->getPrefix($value); - $value_localpart = $this->getLocalPart($value); - $this->message[$pos]['type'] = $value_localpart; - $this->message[$pos]['typePrefix'] = $value_prefix; - if(isset($this->namespaces[$value_prefix])){ - $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; - } else if(isset($attrs['xmlns:'.$value_prefix])) { - $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; - } - // should do something here with the namespace of specified type? - } elseif($key_localpart == 'arrayType'){ - $this->message[$pos]['type'] = 'array'; - /* do arrayType ereg here - [1] arrayTypeValue ::= atype asize - [2] atype ::= QName rank* - [3] rank ::= '[' (',')* ']' - [4] asize ::= '[' length~ ']' - [5] length ::= nextDimension* Digit+ - [6] nextDimension ::= Digit+ ',' - */ - $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; - if(ereg($expr,$value,$regs)){ - $this->message[$pos]['typePrefix'] = $regs[1]; - $this->message[$pos]['arrayTypePrefix'] = $regs[1]; - if (isset($this->namespaces[$regs[1]])) { - $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; - } else if (isset($attrs['xmlns:'.$regs[1]])) { - $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; - } - $this->message[$pos]['arrayType'] = $regs[2]; - $this->message[$pos]['arraySize'] = $regs[3]; - $this->message[$pos]['arrayCols'] = $regs[4]; - } - // specifies nil value (or not) - } elseif ($key_localpart == 'nil'){ - $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); - // some other attribute - } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { - $this->message[$pos]['xattrs']['!' . $key] = $value; - } - - if ($key == 'xmlns') { - $this->default_namespace = $value; - } - // log id - if($key == 'id'){ - $this->ids[$value] = $pos; - } - // root - if($key_localpart == 'root' && $value == 1){ - $this->status = 'method'; - $this->root_struct_name = $name; - $this->root_struct = $pos; - $this->debug("found root struct $this->root_struct_name, pos $pos"); - } - // for doclit - $attstr .= " $key=\"$value\""; - } - // get namespace - must be done after namespace atts are processed - if(isset($prefix)){ - $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; - $this->default_namespace = $this->namespaces[$prefix]; - } else { - $this->message[$pos]['namespace'] = $this->default_namespace; - } - if($this->status == 'header'){ - if ($this->root_header != $pos) { - $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; - } - } elseif($this->root_struct_name != ''){ - $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; - } - } - - /** - * end-element handler - * - * @param resource $parser XML parser object - * @param string $name element name - * @access private - */ - function end_element($parser, $name) { - // position of current element is equal to the last value left in depth_array for my depth - $pos = $this->depth_array[$this->depth--]; - - // get element prefix - if(strpos($name,':')){ - // get ns prefix - $prefix = substr($name,0,strpos($name,':')); - // get unqualified name - $name = substr(strstr($name,':'),1); - } - - // build to native type - if(isset($this->body_position) && $pos > $this->body_position){ - // deal w/ multirefs - if(isset($this->message[$pos]['attrs']['href'])){ - // get id - $id = substr($this->message[$pos]['attrs']['href'],1); - // add placeholder to href array - $this->multirefs[$id][$pos] = 'placeholder'; - // add set a reference to it as the result value - $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; - // build complexType values - } elseif($this->message[$pos]['children'] != ''){ - // if result has already been generated (struct/array) - if(!isset($this->message[$pos]['result'])){ - $this->message[$pos]['result'] = $this->buildVal($pos); - } - // build complexType values of attributes and possibly simpleContent - } elseif (isset($this->message[$pos]['xattrs'])) { - if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { - $this->message[$pos]['xattrs']['!'] = null; - } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { - if (isset($this->message[$pos]['type'])) { - $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } else { - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } else { - $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; - } - } - } - $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; - // set value of simpleType (or nil complexType) - } else { - //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); - if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { - $this->message[$pos]['xattrs']['!'] = null; - } elseif (isset($this->message[$pos]['type'])) { - $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } else { - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } else { - $this->message[$pos]['result'] = $this->message[$pos]['cdata']; - } - } - - /* add value to parent's result, if parent is struct/array - $parent = $this->message[$pos]['parent']; - if($this->message[$parent]['type'] != 'map'){ - if(strtolower($this->message[$parent]['type']) == 'array'){ - $this->message[$parent]['result'][] = $this->message[$pos]['result']; - } else { - $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; - } - } - */ - } - } - - // for doclit - if($this->status == 'header'){ - if ($this->root_header != $pos) { - $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; - } - } elseif($pos >= $this->root_struct){ - $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; - } - // switch status - if($pos == $this->root_struct){ - $this->status = 'body'; - $this->root_struct_namespace = $this->message[$pos]['namespace']; - } elseif($name == 'Body'){ - $this->status = 'envelope'; - } elseif($name == 'Header'){ - $this->status = 'envelope'; - } elseif($name == 'Envelope'){ - // - } - // set parent back to my parent - $this->parent = $this->message[$pos]['parent']; - } - - /** - * element content handler - * - * @param resource $parser XML parser object - * @param string $data element content - * @access private - */ - function character_data($parser, $data){ - $pos = $this->depth_array[$this->depth]; - if ($this->xml_encoding=='UTF-8'){ - // TODO: add an option to disable this for folks who want - // raw UTF-8 that, e.g., might not map to iso-8859-1 - // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); - if($this->decode_utf8){ - $data = utf8_decode($data); - } - } - $this->message[$pos]['cdata'] .= $data; - // for doclit - if($this->status == 'header'){ - $this->responseHeaders .= $data; - } else { - $this->document .= $data; - } - } - - /** - * get the parsed message - * - * @return mixed - * @access public - */ - function get_response(){ - return $this->soapresponse; - } - - /** - * get the parsed headers - * - * @return string XML or empty if no headers - * @access public - */ - function getHeaders(){ - return $this->responseHeaders; - } - - /** - * decodes simple types into PHP variables - * - * @param string $value value to decode - * @param string $type XML type to decode - * @param string $typens XML type namespace to decode - * @return mixed PHP value - * @access private - */ - function decodeSimple($value, $type, $typens) { - // TODO: use the namespace! - if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { - return (string) $value; - } - if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { - return (int) $value; - } - if ($type == 'float' || $type == 'double' || $type == 'decimal') { - return (double) $value; - } - if ($type == 'boolean') { - if (strtolower($value) == 'false' || strtolower($value) == 'f') { - return false; - } - return (boolean) $value; - } - if ($type == 'base64' || $type == 'base64Binary') { - $this->debug('Decode base64 value'); - return base64_decode($value); - } - // obscure numeric types - if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' - || $type == 'nonNegativeInteger' || $type == 'positiveInteger' - || $type == 'unsignedInt' - || $type == 'unsignedShort' || $type == 'unsignedByte') { - return (int) $value; - } - // bogus: parser treats array with no elements as a simple type - if ($type == 'array') { - return array(); - } - // everything else - return (string) $value; - } - - /** - * builds response structures for compound values (arrays/structs) - * and scalars - * - * @param integer $pos position in node tree - * @return mixed PHP value - * @access private - */ - function buildVal($pos){ - if(!isset($this->message[$pos]['type'])){ - $this->message[$pos]['type'] = ''; - } - $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); - // if there are children... - if($this->message[$pos]['children'] != ''){ - $this->debug('in buildVal, there are children'); - $children = explode('|',$this->message[$pos]['children']); - array_shift($children); // knock off empty - // md array - if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ - $r=0; // rowcount - $c=0; // colcount - foreach($children as $child_pos){ - $this->debug("in buildVal, got an MD array element: $r, $c"); - $params[$r][] = $this->message[$child_pos]['result']; - $c++; - if($c == $this->message[$pos]['arrayCols']){ - $c = 0; - $r++; - } - } - // array - } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ - $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); - foreach($children as $child_pos){ - $params[] = &$this->message[$child_pos]['result']; - } - // apache Map type: java hashtable - } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ - $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); - foreach($children as $child_pos){ - $kv = explode("|",$this->message[$child_pos]['children']); - $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; - } - // generic compound type - //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { - } else { - // Apache Vector type: treat as an array - $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); - if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { - $notstruct = 1; - } else { - $notstruct = 0; - } - // - foreach($children as $child_pos){ - if($notstruct){ - $params[] = &$this->message[$child_pos]['result']; - } else { - if (isset($params[$this->message[$child_pos]['name']])) { - // de-serialize repeated element name into an array - if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { - $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); - } - $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; - } else { - $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; - } - } - } - } - if (isset($this->message[$pos]['xattrs'])) { - $this->debug('in buildVal, handling attributes'); - foreach ($this->message[$pos]['xattrs'] as $n => $v) { - $params[$n] = $v; - } - } - // handle simpleContent - if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { - $this->debug('in buildVal, handling simpleContent'); - if (isset($this->message[$pos]['type'])) { - $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } else { - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } else { - $params['!'] = $this->message[$pos]['cdata']; - } - } - } - return is_array($params) ? $params : array(); - } else { - $this->debug('in buildVal, no children, building scalar'); - $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; - if (isset($this->message[$pos]['type'])) { - return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); - } - $parent = $this->message[$pos]['parent']; - if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { - return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); - } - return $this->message[$pos]['cdata']; - } - } -} - - - -?><?php - - - -/** -* -* soapclient higher level class for easy usage. -* -* usage: -* -* // instantiate client with server info -* $soapclient = new soapclient( string path [ ,boolean wsdl] ); -* -* // call method, get results -* echo $soapclient->call( string methodname [ ,array parameters] ); -* -* // bye bye client -* unset($soapclient); -* -* @author Dietrich Ayala <dietrich@ganx4.com> -* @version $Id$ -* @access public -*/ -class soapclient extends nusoap_base { - - var $username = ''; - var $password = ''; - var $authtype = ''; - var $certRequest = array(); - var $requestHeaders = false; // SOAP headers in request (text) - var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) - var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) - var $endpoint; - var $forceEndpoint = ''; // overrides WSDL endpoint - var $proxyhost = ''; - var $proxyport = ''; - var $proxyusername = ''; - var $proxypassword = ''; - var $xml_encoding = ''; // character set encoding of incoming (response) messages - var $http_encoding = false; - var $timeout = 0; // HTTP connection timeout - var $response_timeout = 30; // HTTP response timeout - var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error - var $persistentConnection = false; - var $defaultRpcParams = false; // This is no longer used - var $request = ''; // HTTP request - var $response = ''; // HTTP response - var $responseData = ''; // SOAP payload of response - var $cookies = array(); // Cookies from response or for request - var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() - var $operations = array(); // WSDL operations, empty for WSDL initialization error - - /* - * fault related variables - */ - /** - * @var fault - * @access public - */ - var $fault; - /** - * @var faultcode - * @access public - */ - var $faultcode; - /** - * @var faultstring - * @access public - */ - var $faultstring; - /** - * @var faultdetail - * @access public - */ - var $faultdetail; - - /** - * constructor - * - * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) - * @param bool $wsdl optional, set to true if using WSDL - * @param int $portName optional portName in WSDL document - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @param integer $timeout set the connection timeout - * @param integer $response_timeout set the response timeout - * @access public - */ - function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ - parent::nusoap_base(); - $this->endpoint = $endpoint; - $this->proxyhost = $proxyhost; - $this->proxyport = $proxyport; - $this->proxyusername = $proxyusername; - $this->proxypassword = $proxypassword; - $this->timeout = $timeout; - $this->response_timeout = $response_timeout; - - // make values - if($wsdl){ - if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { - $this->wsdl = $endpoint; - $this->endpoint = $this->wsdl->wsdl; - $this->wsdlFile = $this->endpoint; - $this->debug('existing wsdl instance created from ' . $this->endpoint); - } else { - $this->wsdlFile = $this->endpoint; - - // instantiate wsdl object and parse wsdl file - $this->debug('instantiating wsdl class with doc: '.$endpoint); - $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); - } - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - // catch errors - if($errstr = $this->wsdl->getError()){ - $this->debug('got wsdl error: '.$errstr); - $this->setError('wsdl error: '.$errstr); - } elseif($this->operations = $this->wsdl->getOperations()){ - $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); - $this->endpointType = 'wsdl'; - } else { - $this->debug( 'getOperations returned false'); - $this->setError('no operations defined in the WSDL document!'); - } - } else { - $this->debug("instantiate SOAP with endpoint at $endpoint"); - $this->endpointType = 'soap'; - } - } - - /** - * calls method, returns PHP native type - * - * @param string $method SOAP server URL or path - * @param mixed $params An array, associative or simple, of the parameters - * for the method call, or a string that is the XML - * for the call. For rpc style, this call will - * wrap the XML in a tag named after the method, as - * well as the SOAP Envelope and Body. For document - * style, this will only wrap with the Envelope and Body. - * IMPORTANT: when using an array with document style, - * in which case there - * is really one parameter, the root of the fragment - * used in the call, which encloses what programmers - * normally think of parameters. A parameter array - * *must* include the wrapper. - * @param string $namespace optional method namespace (WSDL can override) - * @param string $soapAction optional SOAPAction value (WSDL can override) - * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers - * @param boolean $rpcParams optional (no longer used) - * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) - * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) - * @return mixed response from SOAP call - * @access public - */ - function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ - $this->operation = $operation; - $this->fault = false; - $this->setError(''); - $this->request = ''; - $this->response = ''; - $this->responseData = ''; - $this->faultstring = ''; - $this->faultcode = ''; - $this->opData = array(); - - $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); - $this->appendDebug('params=' . $this->varDump($params)); - $this->appendDebug('headers=' . $this->varDump($headers)); - if ($headers) { - $this->requestHeaders = $headers; - } - // serialize parameters - if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ - // use WSDL for operation - $this->opData = $opData; - $this->debug("found operation"); - $this->appendDebug('opData=' . $this->varDump($opData)); - if (isset($opData['soapAction'])) { - $soapAction = $opData['soapAction']; - } - if (! $this->forceEndpoint) { - $this->endpoint = $opData['endpoint']; - } else { - $this->endpoint = $this->forceEndpoint; - } - $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; - $style = $opData['style']; - $use = $opData['input']['use']; - // add ns to ns array - if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ - $nsPrefix = 'ns' . rand(1000, 9999); - $this->wsdl->namespaces[$nsPrefix] = $namespace; - } - $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); - // serialize payload - if (is_string($params)) { - $this->debug("serializing param string for WSDL operation $operation"); - $payload = $params; - } elseif (is_array($params)) { - $this->debug("serializing param array for WSDL operation $operation"); - $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); - } else { - $this->debug('params must be array or string'); - $this->setError('params must be array or string'); - return false; - } - $usedNamespaces = $this->wsdl->usedNamespaces; - if (isset($opData['input']['encodingStyle'])) { - $encodingStyle = $opData['input']['encodingStyle']; - } else { - $encodingStyle = ''; - } - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - if ($errstr = $this->wsdl->getError()) { - $this->debug('got wsdl error: '.$errstr); - $this->setError('wsdl error: '.$errstr); - return false; - } - } elseif($this->endpointType == 'wsdl') { - // operation not in WSDL - $this->appendDebug($this->wsdl->getDebug()); - $this->wsdl->clearDebug(); - $this->setError( 'operation '.$operation.' not present.'); - $this->debug("operation '$operation' not present."); - return false; - } else { - // no WSDL - //$this->namespaces['ns1'] = $namespace; - $nsPrefix = 'ns' . rand(1000, 9999); - // serialize - $payload = ''; - if (is_string($params)) { - $this->debug("serializing param string for operation $operation"); - $payload = $params; - } elseif (is_array($params)) { - $this->debug("serializing param array for operation $operation"); - foreach($params as $k => $v){ - $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); - } - } else { - $this->debug('params must be array or string'); - $this->setError('params must be array or string'); - return false; - } - $usedNamespaces = array(); - if ($use == 'encoded') { - $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; - } else { - $encodingStyle = ''; - } - } - // wrap RPC calls with method element - if ($style == 'rpc') { - if ($use == 'literal') { - $this->debug("wrapping RPC request with literal method element"); - if ($namespace) { - $payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>"; - } else { - $payload = "<$operation>" . $payload . "</$operation>"; - } - } else { - $this->debug("wrapping RPC request with encoded method element"); - if ($namespace) { - $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . - $payload . - "</$nsPrefix:$operation>"; - } else { - $payload = "<$operation>" . - $payload . - "</$operation>"; - } - } - } - // serialize envelope - $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); - $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); - $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); - // send - $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); - if($errstr = $this->getError()){ - $this->debug('Error: '.$errstr); - return false; - } else { - $this->return = $return; - $this->debug('sent message successfully and got a(n) '.gettype($return)); - $this->appendDebug('return=' . $this->varDump($return)); - - // fault? - if(is_array($return) && isset($return['faultcode'])){ - $this->debug('got fault'); - $this->setError($return['faultcode'].': '.$return['faultstring']); - $this->fault = true; - foreach($return as $k => $v){ - $this->$k = $v; - $this->debug("$k = $v<br>"); - } - return $return; - } elseif ($style == 'document') { - // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), - // we are only going to return the first part here...sorry about that - return $return; - } else { - // array of return values - if(is_array($return)){ - // multiple 'out' parameters, which we return wrapped up - // in the array - if(sizeof($return) > 1){ - return $return; - } - // single 'out' parameter (normally the return value) - $return = array_shift($return); - $this->debug('return shifted value: '); - $this->appendDebug($this->varDump($return)); - return $return; - // nothing returned (ie, echoVoid) - } else { - return ""; - } - } - } - } - - /** - * get available data pertaining to an operation - * - * @param string $operation operation name - * @return array array of data pertaining to the operation - * @access public - */ - function getOperationData($operation){ - if(isset($this->operations[$operation])){ - return $this->operations[$operation]; - } - $this->debug("No data for operation: $operation"); - } - - /** - * send the SOAP message - * - * Note: if the operation has multiple return values - * the return value of this method will be an array - * of those values. - * - * @param string $msg a SOAPx4 soapmsg object - * @param string $soapaction SOAPAction value - * @param integer $timeout set connection timeout in seconds - * @param integer $response_timeout set response timeout in seconds - * @return mixed native PHP types. - * @access private - */ - function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { - $this->checkCookies(); - // detect transport - switch(true){ - // http(s) - case ereg('^http',$this->endpoint): - $this->debug('transporting via HTTP'); - if($this->persistentConnection == true && is_object($this->persistentConnection)){ - $http =& $this->persistentConnection; - } else { - $http = new soap_transport_http($this->endpoint); - if ($this->persistentConnection) { - $http->usePersistentConnection(); - } - } - $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); - $http->setSOAPAction($soapaction); - if($this->proxyhost && $this->proxyport){ - $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); - } - if($this->authtype != '') { - $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); - } - if($this->http_encoding != ''){ - $http->setEncoding($this->http_encoding); - } - $this->debug('sending message, length='.strlen($msg)); - if(ereg('^http:',$this->endpoint)){ - //if(strpos($this->endpoint,'http:')){ - $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); - } elseif(ereg('^https',$this->endpoint)){ - //} elseif(strpos($this->endpoint,'https:')){ - //if(phpversion() == '4.3.0-dev'){ - //$response = $http->send($msg,$timeout,$response_timeout); - //$this->request = $http->outgoing_payload; - //$this->response = $http->incoming_payload; - //} else - $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); - } else { - $this->setError('no http/s in endpoint url'); - } - $this->request = $http->outgoing_payload; - $this->response = $http->incoming_payload; - $this->appendDebug($http->getDebug()); - $this->UpdateCookies($http->incoming_cookies); - - // save transport object if using persistent connections - if ($this->persistentConnection) { - $http->clearDebug(); - if (!is_object($this->persistentConnection)) { - $this->persistentConnection = $http; - } - } - - if($err = $http->getError()){ - $this->setError('HTTP Error: '.$err); - return false; - } elseif($this->getError()){ - return false; - } else { - $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); - return $this->parseResponse($http->incoming_headers, $this->responseData); - } - break; - default: - $this->setError('no transport found, or selected transport is not yet supported!'); - return false; - break; - } - } - - /** - * processes SOAP message returned from server - * - * @param array $headers The HTTP headers - * @param string $data unprocessed response data from server - * @return mixed value of the message, decoded into a PHP type - * @access private - */ - function parseResponse($headers, $data) { - $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); - if (!strstr($headers['content-type'], 'text/xml')) { - $this->setError('Response not of type text/xml'); - return false; - } - if (strpos($headers['content-type'], '=')) { - $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); - $this->debug('Got response encoding: ' . $enc); - if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ - $this->xml_encoding = strtoupper($enc); - } else { - $this->xml_encoding = 'US-ASCII'; - } - } else { - // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 - $this->xml_encoding = 'ISO-8859-1'; - } - $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); - $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8); - // add parser debug data to our debug - $this->appendDebug($parser->getDebug()); - // if parse errors - if($errstr = $parser->getError()){ - $this->setError( $errstr); - // destroy the parser object - unset($parser); - return false; - } else { - // get SOAP headers - $this->responseHeaders = $parser->getHeaders(); - // get decoded message - $return = $parser->get_response(); - // add document for doclit support - $this->document = $parser->document; - // destroy the parser object - unset($parser); - // return decode message - return $return; - } - } - - /** - * sets the SOAP endpoint, which can override WSDL - * - * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override - * @access public - */ - function setEndpoint($endpoint) { - $this->forceEndpoint = $endpoint; - } - - /** - * set the SOAP headers - * - * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers - * @access public - */ - function setHeaders($headers){ - $this->requestHeaders = $headers; - } - - /** - * get the SOAP response headers (namespace resolution incomplete) - * - * @return string - * @access public - */ - function getHeaders(){ - return $this->responseHeaders; - } - - /** - * set proxy info here - * - * @param string $proxyhost - * @param string $proxyport - * @param string $proxyusername - * @param string $proxypassword - * @access public - */ - function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { - $this->proxyhost = $proxyhost; - $this->proxyport = $proxyport; - $this->proxyusername = $proxyusername; - $this->proxypassword = $proxypassword; - } - - /** - * if authenticating, set user credentials here - * - * @param string $username - * @param string $password - * @param string $authtype (basic|digest|certificate) - * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) - * @access public - */ - function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { - $this->username = $username; - $this->password = $password; - $this->authtype = $authtype; - $this->certRequest = $certRequest; - } - - /** - * use HTTP encoding - * - * @param string $enc - * @access public - */ - function setHTTPEncoding($enc='gzip, deflate'){ - $this->http_encoding = $enc; - } - - /** - * use HTTP persistent connections if possible - * - * @access public - */ - function useHTTPPersistentConnection(){ - $this->persistentConnection = true; - } - - /** - * gets the default RPC parameter setting. - * If true, default is that call params are like RPC even for document style. - * Each call() can override this value. - * - * This is no longer used. - * - * @return boolean - * @access public - * @deprecated - */ - function getDefaultRpcParams() { - return $this->defaultRpcParams; - } - - /** - * sets the default RPC parameter setting. - * If true, default is that call params are like RPC even for document style - * Each call() can override this value. - * - * This is no longer used. - * - * @param boolean $rpcParams - * @access public - * @deprecated - */ - function setDefaultRpcParams($rpcParams) { - $this->defaultRpcParams = $rpcParams; - } - - /** - * dynamically creates an instance of a proxy class, - * allowing user to directly call methods from wsdl - * - * @return object soap_proxy object - * @access public - */ - function getProxy(){ - $r = rand(); - $evalStr = $this->_getProxyClassCode($r); - //$this->debug("proxy class: $evalStr"; - // eval the class - eval($evalStr); - // instantiate proxy object - eval("\$proxy = new soap_proxy_$r('');"); - // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice - $proxy->endpointType = 'wsdl'; - $proxy->wsdlFile = $this->wsdlFile; - $proxy->wsdl = $this->wsdl; - $proxy->operations = $this->operations; - $proxy->defaultRpcParams = $this->defaultRpcParams; - // transfer other state - $proxy->username = $this->username; - $proxy->password = $this->password; - $proxy->authtype = $this->authtype; - $proxy->proxyhost = $this->proxyhost; - $proxy->proxyport = $this->proxyport; - $proxy->proxyusername = $this->proxyusername; - $proxy->proxypassword = $this->proxypassword; - $proxy->timeout = $this->timeout; - $proxy->response_timeout = $this->response_timeout; - $proxy->http_encoding = $this->http_encoding; - $proxy->persistentConnection = $this->persistentConnection; - $proxy->requestHeaders = $this->requestHeaders; - $proxy->soap_defencoding = $this->soap_defencoding; - $proxy->endpoint = $this->endpoint; - $proxy->forceEndpoint = $this->forceEndpoint; - return $proxy; - } - - /** - * dynamically creates proxy class code - * - * @return string PHP/NuSOAP code for the proxy class - * @access private - */ - function _getProxyClassCode($r) { - if ($this->endpointType != 'wsdl') { - $evalStr = 'A proxy can only be created for a WSDL client'; - $this->setError($evalStr); - return $evalStr; - } - $evalStr = ''; - foreach ($this->operations as $operation => $opData) { - if ($operation != '') { - // create param string and param comment string - if (sizeof($opData['input']['parts']) > 0) { - $paramStr = ''; - $paramArrayStr = ''; - $paramCommentStr = ''; - foreach ($opData['input']['parts'] as $name => $type) { - $paramStr .= "\$$name, "; - $paramArrayStr .= "'$name' => \$$name, "; - $paramCommentStr .= "$type \$$name, "; - } - $paramStr = substr($paramStr, 0, strlen($paramStr)-2); - $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); - $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); - } else { - $paramStr = ''; - $paramCommentStr = 'void'; - } - $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; - $evalStr .= "// $paramCommentStr - function " . str_replace('.', '__', $operation) . "($paramStr) { - \$params = array($paramArrayStr); - return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); - } - "; - unset($paramStr); - unset($paramCommentStr); - } - } - $evalStr = 'class soap_proxy_'.$r.' extends soapclient { - '.$evalStr.' -}'; - return $evalStr; - } - - /** - * dynamically creates proxy class code - * - * @return string PHP/NuSOAP code for the proxy class - * @access public - */ - function getProxyClassCode() { - $r = rand(); - return $this->_getProxyClassCode($r); - } - - /** - * gets the HTTP body for the current request. - * - * @param string $soapmsg The SOAP payload - * @return string The HTTP body, which includes the SOAP payload - * @access private - */ - function getHTTPBody($soapmsg) { - return $soapmsg; - } - - /** - * gets the HTTP content type for the current request. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type for the current request. - * @access private - */ - function getHTTPContentType() { - return 'text/xml'; - } - - /** - * gets the HTTP content type charset for the current request. - * returns false for non-text content types. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type charset for the current request. - * @access private - */ - function getHTTPContentTypeCharset() { - return $this->soap_defencoding; - } - - /* - * whether or not parser should decode utf8 element content - * - * @return always returns true - * @access public - */ - function decodeUTF8($bool){ - $this->decode_utf8 = $bool; - return true; - } - - /** - * adds a new Cookie into $this->cookies array - * - * @param string $name Cookie Name - * @param string $value Cookie Value - * @return if cookie-set was successful returns true, else false - * @access public - */ - function setCookie($name, $value) { - if (strlen($name) == 0) { - return false; - } - $this->cookies[] = array('name' => $name, 'value' => $value); - return true; - } - - /** - * gets all Cookies - * - * @return array with all internal cookies - * @access public - */ - function getCookies() { - return $this->cookies; - } - - /** - * checks all Cookies and delete those which are expired - * - * @return always return true - * @access private - */ - function checkCookies() { - if (sizeof($this->cookies) == 0) { - return true; - } - $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); - $curr_cookies = $this->cookies; - $this->cookies = array(); - foreach ($curr_cookies as $cookie) { - if (! is_array($cookie)) { - $this->debug('Remove cookie that is not an array'); - continue; - } - if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { - if (strtotime($cookie['expires']) > time()) { - $this->cookies[] = $cookie; - } else { - $this->debug('Remove expired cookie ' . $cookie['name']); - } - } else { - $this->cookies[] = $cookie; - } - } - $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); - return true; - } - - /** - * updates the current cookies with a new set - * - * @param array $cookies new cookies with which to update current ones - * @return always return true - * @access private - */ - function UpdateCookies($cookies) { - if (sizeof($this->cookies) == 0) { - // no existing cookies: take whatever is new - if (sizeof($cookies) > 0) { - $this->debug('Setting new cookie(s)'); - $this->cookies = $cookies; - } - return true; - } - if (sizeof($cookies) == 0) { - // no new cookies: keep what we've got - return true; - } - // merge - foreach ($cookies as $newCookie) { - if (!is_array($newCookie)) { - continue; - } - if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { - continue; - } - $newName = $newCookie['name']; - - $found = false; - for ($i = 0; $i < count($this->cookies); $i++) { - $cookie = $this->cookies[$i]; - if (!is_array($cookie)) { - continue; - } - if (!isset($cookie['name'])) { - continue; - } - if ($newName != $cookie['name']) { - continue; - } - $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; - $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; - if ($newDomain != $domain) { - continue; - } - $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; - $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; - if ($newPath != $path) { - continue; - } - $this->cookies[$i] = $newCookie; - $found = true; - $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); - break; - } - if (! $found) { - $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); - $this->cookies[] = $newCookie; - } - } - return true; - } -} -?> +<?php + +/* +$Id$ + +NuSOAP - Web Services Toolkit for PHP + +Copyright (c) 2002 NuSphere Corporation + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you have any questions or comments, please email: + +Dietrich Ayala +dietrich@ganx4.com +http://dietrich.ganx4.com/nusoap + +NuSphere Corporation +http://www.nusphere.com + +*/ + +/* load classes + +// necessary classes +require_once('class.soapclient.php'); +require_once('class.soap_val.php'); +require_once('class.soap_parser.php'); +require_once('class.soap_fault.php'); + +// transport classes +require_once('class.soap_transport_http.php'); + +// optional add-on classes +require_once('class.xmlschema.php'); +require_once('class.wsdl.php'); + +// server class +require_once('class.soap_server.php');*/ + +// class variable emulation +// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html +$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; + +/** +* +* nusoap_base +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class nusoap_base { + /** + * Identification for HTTP headers. + * + * @var string + * @access private + */ + var $title = 'NuSOAP'; + /** + * Version for HTTP headers. + * + * @var string + * @access private + */ + var $version = '0.7.2'; + /** + * CVS revision for HTTP headers. + * + * @var string + * @access private + */ + var $revision = '$Revision$'; + /** + * Current error string (manipulated by getError/setError) + * + * @var string + * @access private + */ + var $error_str = ''; + /** + * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) + * + * @var string + * @access private + */ + var $debug_str = ''; + /** + * toggles automatic encoding of special characters as entities + * (should always be true, I think) + * + * @var boolean + * @access private + */ + var $charencoding = true; + /** + * the debug level for this instance + * + * @var integer + * @access private + */ + var $debugLevel; + + /** + * set schema version + * + * @var string + * @access public + */ + var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + /** + * charset encoding for outgoing messages + * + * @var string + * @access public + */ + var $soap_defencoding = 'ISO-8859-1'; + //var $soap_defencoding = 'UTF-8'; + + /** + * namespaces in an array of prefix => uri + * + * this is "seeded" by a set of constants, but it may be altered by code + * + * @var array + * @access public + */ + var $namespaces = array( + 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'xsd' => 'http://www.w3.org/2001/XMLSchema', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' + ); + + /** + * namespaces used in the current context, e.g. during serialization + * + * @var array + * @access private + */ + var $usedNamespaces = array(); + + /** + * XML Schema types in an array of uri => (array of xml type => php type) + * is this legacy yet? + * no, this is used by the xmlschema class to verify type => namespace mappings. + * @var array + * @access public + */ + var $typemap = array( + 'http://www.w3.org/2001/XMLSchema' => array( + 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', + 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', + 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', + // abstract "any" types + 'anyType'=>'string','anySimpleType'=>'string', + // derived datatypes + 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', + 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', + 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', + 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), + 'http://www.w3.org/2000/10/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://www.w3.org/1999/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), + 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), + 'http://xml.apache.org/xml-soap' => array('Map') + ); + + /** + * XML entities to convert + * + * @var array + * @access public + * @deprecated + * @see expandEntities + */ + var $xmlEntities = array('quot' => '"','amp' => '&', + 'lt' => '<','gt' => '>','apos' => "'"); + + /** + * constructor + * + * @access public + */ + function nusoap_base() { + $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * gets the global debug level, which applies to future instances + * + * @return integer Debug level 0-9, where 0 turns off + * @access public + */ + function getGlobalDebugLevel() { + return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * sets the global debug level, which applies to future instances + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setGlobalDebugLevel($level) { + $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; + } + + /** + * gets the debug level for this instance + * + * @return int Debug level 0-9, where 0 turns off + * @access public + */ + function getDebugLevel() { + return $this->debugLevel; + } + + /** + * sets the debug level for this instance + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setDebugLevel($level) { + $this->debugLevel = $level; + } + + /** + * adds debug data to the instance debug string with formatting + * + * @param string $string debug data + * @access private + */ + function debug($string){ + if ($this->debugLevel > 0) { + $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); + } + } + + /** + * adds debug data to the instance debug string without formatting + * + * @param string $string debug data + * @access public + */ + function appendDebug($string){ + if ($this->debugLevel > 0) { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str .= $string; + } + } + + /** + * clears the current debug data for this instance + * + * @access public + */ + function clearDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str = ''; + } + + /** + * gets the current debug data for this instance + * + * @return debug data + * @access public + */ + function &getDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + return $this->debug_str; + } + + /** + * gets the current debug data for this instance as an XML comment + * this may change the contents of the debug data + * + * @return debug data as an XML comment + * @access public + */ + function &getDebugAsXMLComment() { + // it would be nice to use a memory stream here to use + // memory more efficiently + while (strpos($this->debug_str, '--')) { + $this->debug_str = str_replace('--', '- -', $this->debug_str); + } + return "<!--\n" . $this->debug_str . "\n-->"; + } + + /** + * expands entities, e.g. changes '<' to '<'. + * + * @param string $val The string in which to expand entities. + * @access private + */ + function expandEntities($val) { + if ($this->charencoding) { + $val = str_replace('&', '&', $val); + $val = str_replace("'", ''', $val); + $val = str_replace('"', '"', $val); + $val = str_replace('<', '<', $val); + $val = str_replace('>', '>', $val); + } + return $val; + } + + /** + * returns error string if present + * + * @return mixed error string or false + * @access public + */ + function getError(){ + if($this->error_str != ''){ + return $this->error_str; + } + return false; + } + + /** + * sets error string + * + * @return boolean $string error string + * @access private + */ + function setError($str){ + $this->error_str = $str; + } + + /** + * detect if array is a simple array or a struct (associative array) + * + * @param mixed $val The PHP array + * @return string (arraySimple|arrayStruct) + * @access private + */ + function isArraySimpleOrStruct($val) { + $keyList = array_keys($val); + foreach ($keyList as $keyListValue) { + if (!is_int($keyListValue)) { + return 'arrayStruct'; + } + } + return 'arraySimple'; + } + + /** + * serializes PHP values in accordance w/ section 5. Type information is + * not serialized if $use == 'literal'. + * + * @param mixed $val The value to serialize + * @param string $name The name (local part) of the XML element + * @param string $type The XML schema type (local part) for the element + * @param string $name_ns The namespace for the name of the XML element + * @param string $type_ns The namespace for the type of the element + * @param array $attributes The attributes to serialize as name=>value pairs + * @param string $use The WSDL "use" (encoded|literal) + * @return string The serialized element, possibly with child elements + * @access public + */ + function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ + $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); + $this->appendDebug('value=' . $this->varDump($val)); + $this->appendDebug('attributes=' . $this->varDump($attributes)); + + if(is_object($val) && get_class($val) == 'soapval'){ + return $val->serialize($use); + } + // force valid name if necessary + if (is_numeric($name)) { + $name = '__numeric_' . $name; + } elseif (! $name) { + $name = 'noname'; + } + // if name has ns, add ns prefix to name + $xmlns = ''; + if($name_ns){ + $prefix = 'nu'.rand(1000,9999); + $name = $prefix.':'.$name; + $xmlns .= " xmlns:$prefix=\"$name_ns\""; + } + // if type is prefixed, create type prefix + if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ + // need to fix this. shouldn't default to xsd if no ns specified + // w/o checking against typemap + $type_prefix = 'xsd'; + } elseif($type_ns){ + $type_prefix = 'ns'.rand(1000,9999); + $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; + } + // serialize attributes if present + $atts = ''; + if($attributes){ + foreach($attributes as $k => $v){ + $atts .= " $k=\"".$this->expandEntities($v).'"'; + } + } + // serialize null value + if (is_null($val)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + return "<$name$xmlns $atts/>"; + } else { + if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; + } + } + // serialize if an xsd built-in primitive type + if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ + if (is_bool($val)) { + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + } else if (is_string($val)) { + $val = $this->expandEntities($val); + } + if ($use == 'literal') { + return "<$name$xmlns $atts>$val</$name>"; + } else { + return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>"; + } + } + // detect type and serialize + $xml = ''; + switch(true) { + case (is_bool($val) || $type == 'boolean'): + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>"; + } + break; + case (is_int($val) || is_long($val) || $type == 'int'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>"; + } + break; + case (is_float($val)|| is_double($val) || $type == 'float'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>"; + } + break; + case (is_string($val) || $type == 'string'): + $val = $this->expandEntities($val); + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val</$name>"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>"; + } + break; + case is_object($val): + if (! $name) { + $name = get_class($val); + $this->debug("In serialize_val, used class name $name as element name"); + } else { + $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); + } + foreach(get_object_vars($val) as $k => $v){ + $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); + } + $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>'; + break; + break; + case (is_array($val) || $type): + // detect if struct or array + $valueType = $this->isArraySimpleOrStruct($val); + if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ + $i = 0; + if(is_array($val) && count($val)> 0){ + foreach($val as $v){ + if(is_object($v) && get_class($v) == 'soapval'){ + $tt_ns = $v->type_ns; + $tt = $v->type; + } elseif (is_array($v)) { + $tt = $this->isArraySimpleOrStruct($v); + } else { + $tt = gettype($v); + } + $array_types[$tt] = 1; + // TODO: for literal, the name should be $name + $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); + ++$i; + } + if(count($array_types) > 1){ + $array_typename = 'xsd:anyType'; + } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { + if ($tt == 'integer') { + $tt = 'int'; + } + $array_typename = 'xsd:'.$tt; + } elseif(isset($tt) && $tt == 'arraySimple'){ + $array_typename = 'SOAP-ENC:Array'; + } elseif(isset($tt) && $tt == 'arrayStruct'){ + $array_typename = 'unnamed_struct_use_soapval'; + } else { + // if type is prefixed, create type prefix + if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ + $array_typename = 'xsd:' . $tt; + } elseif ($tt_ns) { + $tt_prefix = 'ns' . rand(1000, 9999); + $array_typename = "$tt_prefix:$tt"; + $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; + } else { + $array_typename = $tt; + } + } + $array_type = $i; + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; + } + // empty array + } else { + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; + } + } + // TODO: for array in literal, there is no wrapper here + $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>"; + } else { + // got a struct + if(isset($type) && isset($type_prefix)){ + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>"; + } else { + $xml .= "<$name$xmlns$type_str$atts>"; + } + foreach($val as $k => $v){ + // Apache Map + if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { + $xml .= '<item>'; + $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); + $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); + $xml .= '</item>'; + } else { + $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } + $xml .= "</$name>"; + } + break; + default: + $xml .= 'not detected, got '.gettype($val).' for '.$val; + break; + } + return $xml; + } + + /** + * serializes a message + * + * @param string $body the XML of the SOAP body + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param array $namespaces optional the namespaces used in generating the body and headers + * @param string $style optional (rpc|document) + * @param string $use optional (encoded|literal) + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @return string the message + * @access public + */ + function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ + // TODO: add an option to automatically run utf8_encode on $body and $headers + // if $this->soap_defencoding is UTF-8. Not doing this automatically allows + // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 + + $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); + $this->debug("headers:"); + $this->appendDebug($this->varDump($headers)); + $this->debug("namespaces:"); + $this->appendDebug($this->varDump($namespaces)); + + // serialize namespaces + $ns_string = ''; + foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ + $ns_string .= " xmlns:$k=\"$v\""; + } + if($encodingStyle) { + $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; + } + + // serialize headers + if($headers){ + if (is_array($headers)) { + $xml = ''; + foreach ($headers as $header) { + $xml .= $this->serialize_val($header, false, false, false, false, false, $use); + } + $headers = $xml; + $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); + } + $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>"; + } + // serialize envelope + return + '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">". + '<SOAP-ENV:Envelope'.$ns_string.">". + $headers. + "<SOAP-ENV:Body>". + $body. + "</SOAP-ENV:Body>". + "</SOAP-ENV:Envelope>"; + } + + /** + * formats a string to be inserted into an HTML stream + * + * @param string $str The string to format + * @return string The formatted string + * @access public + * @deprecated + */ + function formatDump($str){ + $str = htmlspecialchars($str); + return nl2br($str); + } + + /** + * contracts (changes namespace to prefix) a qualified name + * + * @param string $qname qname + * @return string contracted qname + * @access private + */ + function contractQname($qname){ + // get element namespace + //$this->xdebug("Contract $qname"); + if (strrpos($qname, ':')) { + // get unqualified name + $name = substr($qname, strrpos($qname, ':') + 1); + // get ns + $ns = substr($qname, 0, strrpos($qname, ':')); + $p = $this->getPrefixFromNamespace($ns); + if ($p) { + return $p . ':' . $name; + } + return $qname; + } else { + return $qname; + } + } + + /** + * expands (changes prefix to namespace) a qualified name + * + * @param string $string qname + * @return string expanded qname + * @access private + */ + function expandQname($qname){ + // get element prefix + if(strpos($qname,':') && !ereg('^http://',$qname)){ + // get unqualified name + $name = substr(strstr($qname,':'),1); + // get ns prefix + $prefix = substr($qname,0,strpos($qname,':')); + if(isset($this->namespaces[$prefix])){ + return $this->namespaces[$prefix].':'.$name; + } else { + return $qname; + } + } else { + return $qname; + } + } + + /** + * returns the local part of a prefixed string + * returns the original string, if not prefixed + * + * @param string $str The prefixed string + * @return string The local part + * @access public + */ + function getLocalPart($str){ + if($sstr = strrchr($str,':')){ + // get unqualified name + return substr( $sstr, 1 ); + } else { + return $str; + } + } + + /** + * returns the prefix part of a prefixed string + * returns false, if not prefixed + * + * @param string $str The prefixed string + * @return mixed The prefix or false if there is no prefix + * @access public + */ + function getPrefix($str){ + if($pos = strrpos($str,':')){ + // get prefix + return substr($str,0,$pos); + } + return false; + } + + /** + * pass it a prefix, it returns a namespace + * + * @param string $prefix The prefix + * @return mixed The namespace, false if no namespace has the specified prefix + * @access public + */ + function getNamespaceFromPrefix($prefix){ + if (isset($this->namespaces[$prefix])) { + return $this->namespaces[$prefix]; + } + //$this->setError("No namespace registered for prefix '$prefix'"); + return false; + } + + /** + * returns the prefix for a given namespace (or prefix) + * or false if no prefixes registered for the given namespace + * + * @param string $ns The namespace + * @return mixed The prefix, false if the namespace has no prefixes + * @access public + */ + function getPrefixFromNamespace($ns) { + foreach ($this->namespaces as $p => $n) { + if ($ns == $n || $ns == $p) { + $this->usedNamespaces[$p] = $n; + return $p; + } + } + return false; + } + + /** + * returns the time in ODBC canonical form with microseconds + * + * @return string The time in ODBC canonical form with microseconds + * @access public + */ + function getmicrotime() { + if (function_exists('gettimeofday')) { + $tod = gettimeofday(); + $sec = $tod['sec']; + $usec = $tod['usec']; + } else { + $sec = time(); + $usec = 0; + } + return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); + } + + /** + * Returns a string with the output of var_dump + * + * @param mixed $data The variable to var_dump + * @return string The output of var_dump + * @access public + */ + function varDump($data) { + ob_start(); + var_dump($data); + $ret_val = ob_get_contents(); + ob_end_clean(); + return $ret_val; + } +} + +// XML Schema Datatype Helper Functions + +//xsd:dateTime helpers + +/** +* convert unix timestamp to ISO 8601 compliant date string +* +* @param string $timestamp Unix time stamp +* @access public +*/ +function timestamp_to_iso8601($timestamp,$utc=true){ + $datestr = date('Y-m-d\TH:i:sO',$timestamp); + if($utc){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + + if(ereg($eregStr,$datestr,$regs)){ + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); + } + return false; + } else { + return $datestr; + } +} + +/** +* convert ISO 8601 compliant date string to unix timestamp +* +* @param string $datestr ISO 8601 compliant date string +* @access public +*/ +function iso8601_to_timestamp($datestr){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + if(ereg($eregStr,$datestr,$regs)){ + // not utc + if($regs[8] != 'Z'){ + $op = substr($regs[8],0,1); + $h = substr($regs[8],1,2); + $m = substr($regs[8],strlen($regs[8])-2,2); + if($op == '-'){ + $regs[4] = $regs[4] + $h; + $regs[5] = $regs[5] + $m; + } elseif($op == '+'){ + $regs[4] = $regs[4] - $h; + $regs[5] = $regs[5] - $m; + } + } + return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); + } else { + return false; + } +} + +/** +* sleeps some number of microseconds +* +* @param string $usec the number of microseconds to sleep +* @access public +* @deprecated +*/ +function usleepWindows($usec) +{ + $start = gettimeofday(); + + do + { + $stop = gettimeofday(); + $timePassed = 1000000 * ($stop['sec'] - $start['sec']) + + $stop['usec'] - $start['usec']; + } + while ($timePassed < $usec); +} + +?><?php + + + +/** +* Contains information for a SOAP fault. +* Mainly used for returning faults from deployed functions +* in a server instance. +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_fault extends nusoap_base { + /** + * The fault code (client|server) + * @var string + * @access private + */ + var $faultcode; + /** + * The fault actor + * @var string + * @access private + */ + var $faultactor; + /** + * The fault string, a description of the fault + * @var string + * @access private + */ + var $faultstring; + /** + * The fault detail, typically a string or array of string + * @var mixed + * @access private + */ + var $faultdetail; + + /** + * constructor + * + * @param string $faultcode (client | server) + * @param string $faultactor only used when msg routed between multiple actors + * @param string $faultstring human readable error message + * @param mixed $faultdetail detail, typically a string or array of string + */ + function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ + parent::nusoap_base(); + $this->faultcode = $faultcode; + $this->faultactor = $faultactor; + $this->faultstring = $faultstring; + $this->faultdetail = $faultdetail; + } + + /** + * serialize a fault + * + * @return string The serialization of the fault instance. + * @access public + */ + function serialize(){ + $ns_string = ''; + foreach($this->namespaces as $k => $v){ + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'. + '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n". + '<SOAP-ENV:Body>'. + '<SOAP-ENV:Fault>'. + $this->serialize_val($this->faultcode, 'faultcode'). + $this->serialize_val($this->faultactor, 'faultactor'). + $this->serialize_val($this->faultstring, 'faultstring'). + $this->serialize_val($this->faultdetail, 'detail'). + '</SOAP-ENV:Fault>'. + '</SOAP-ENV:Body>'. + '</SOAP-ENV:Envelope>'; + return $return_msg; + } +} + + + +?><?php + + + +/** +* parses an XML Schema, allows access to it's data, other utility methods +* no validation... yet. +* very experimental and limited. As is discussed on XML-DEV, I'm one of the people +* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty +* tutorials I refer to :) +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class XMLSchema extends nusoap_base { + + // files + var $schema = ''; + var $xml = ''; + // namespaces + var $enclosingNamespaces; + // schema info + var $schemaInfo = array(); + var $schemaTargetNamespace = ''; + // types, elements, attributes defined by the schema + var $attributes = array(); + var $complexTypes = array(); + var $complexTypeStack = array(); + var $currentComplexType = null; + var $elements = array(); + var $elementStack = array(); + var $currentElement = null; + var $simpleTypes = array(); + var $simpleTypeStack = array(); + var $currentSimpleType = null; + // imports + var $imports = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + var $message = array(); + var $defaultNamespace = array(); + + /** + * constructor + * + * @param string $schema schema document URI + * @param string $xml xml document URI + * @param string $namespaces namespaces defined in enclosing XML + * @access public + */ + function XMLSchema($schema='',$xml='',$namespaces=array()){ + parent::nusoap_base(); + $this->debug('xmlschema class instantiated, inside constructor'); + // files + $this->schema = $schema; + $this->xml = $xml; + + // namespaces + $this->enclosingNamespaces = $namespaces; + $this->namespaces = array_merge($this->namespaces, $namespaces); + + // parse schema file + if($schema != ''){ + $this->debug('initial schema file: '.$schema); + $this->parseFile($schema, 'schema'); + } + + // parse xml file + if($xml != ''){ + $this->debug('initial xml file: '.$xml); + $this->parseFile($xml, 'xml'); + } + + } + + /** + * parse an XML file + * + * @param string $xml, path/URL to XML file + * @param string $type, (schema | xml) + * @return boolean + * @access public + */ + function parseFile($xml,$type){ + // parse xml file + if($xml != ""){ + $xmlStr = @join("",@file($xml)); + if($xmlStr == ""){ + $msg = 'Error reading XML from '.$xml; + $this->setError($msg); + $this->debug($msg); + return false; + } else { + $this->debug("parsing $xml"); + $this->parseString($xmlStr,$type); + $this->debug("done parsing $xml"); + return true; + } + } + return false; + } + + /** + * parse an XML string + * + * @param string $xml path or URL + * @param string $type, (schema|xml) + * @access private + */ + function parseString($xml,$type){ + // parse xml string + if($xml != ""){ + + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + + // Set the object for the parser. + xml_set_object($this->parser, $this); + + // Set the element handlers for the parser. + if($type == "schema"){ + xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); + xml_set_character_data_handler($this->parser,'schemaCharacterData'); + } elseif($type == "xml"){ + xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); + xml_set_character_data_handler($this->parser,'xmlCharacterData'); + } + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $errstr = sprintf('XML error parsing XML schema on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $xml); + $this->setError($errstr); + } + + xml_parser_free($this->parser); + } else{ + $this->debug('no xml passed to parseString()!!'); + $this->setError('no xml passed to parseString()!!'); + } + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function schemaStartElement($parser, $name, $attrs) { + + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + if ($depth > 0) { + $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; + } else { + $this->defaultNamespace[$pos] = false; + } + + // get element prefix + if($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + + // loop thru attributes, expanding, and registering namespace declarations + if(count($attrs) > 0){ + foreach($attrs as $k => $v){ + // if ns declarations, add to class level array of valid namespaces + if(ereg("^xmlns",$k)){ + //$this->xdebug("$k: $v"); + //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); + if($ns_prefix = substr(strrchr($k,':'),1)){ + //$this->xdebug("Add namespace[$ns_prefix] = $v"); + $this->namespaces[$ns_prefix] = $v; + } else { + $this->defaultNamespace[$pos] = $v; + if (! $this->getPrefixFromNamespace($v)) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; + } + } + if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v.'-instance'; + } + } + } + foreach($attrs as $k => $v){ + // expand each attribute + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // find status, register data + switch($name){ + case 'all': // (optional) compositor content for a complexType + case 'choice': + case 'group': + case 'sequence': + //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); + $this->complexTypes[$this->currentComplexType]['compositor'] = $name; + //if($name == 'all' || $name == 'sequence'){ + // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + //} + break; + case 'attribute': // complexType attribute + //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); + $this->xdebug("parsing attribute:"); + $this->appendDebug($this->varDump($attrs)); + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['attributeFormDefault']; + } + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + if (!strpos($v, ':')) { + // no namespace in arrayType attribute value... + if ($this->defaultNamespace[$pos]) { + // ...so use the default + $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } + } + } + if(isset($attrs['name'])){ + $this->attributes[$attrs['name']] = $attrs; + $aname = $attrs['name']; + } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $aname = ''; + } + } elseif(isset($attrs['ref'])){ + $aname = $attrs['ref']; + $this->attributes[$attrs['ref']] = $attrs; + } + + if($this->currentComplexType){ // This should *always* be + $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; + } + // arrayType attribute + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + $prefix = $this->getPrefix($aname); + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $v = ''; + } + if(strpos($v,'[,]')){ + $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; + } + $v = substr($v,0,strpos($v,'[')); // clip the [] + if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ + $v = $this->XMLSchemaVersion.':'.$v; + } + $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; + } + break; + case 'complexContent': // (optional) content for a complexType + break; + case 'complexType': + array_push($this->complexTypeStack, $this->currentComplexType); + if(isset($attrs['name'])){ + $this->xdebug('processing named complexType '.$attrs['name']); + //$this->currentElement = false; + $this->currentComplexType = $attrs['name']; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // <complexType name="ListOfString" base="soap:Array"> + // <sequence> + // <element name="string" type="xsd:string" + // minOccurs="0" maxOccurs="unbounded" /> + // </sequence> + // </complexType> + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + }else{ + $this->xdebug('processing unnamed complexType for element '.$this->currentElement); + $this->currentComplexType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // <complexType name="ListOfString" base="soap:Array"> + // <sequence> + // <element name="string" type="xsd:string" + // minOccurs="0" maxOccurs="unbounded" /> + // </sequence> + // </complexType> + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + } + break; + case 'element': + array_push($this->elementStack, $this->currentElement); + // elements defined as part of a complex type should + // not really be added to $this->elements, but for some + // reason, they are + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['elementFormDefault']; + } + if(isset($attrs['type'])){ + $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); + if (! $this->getPrefix($attrs['type'])) { + if ($this->defaultNamespace[$pos]) { + $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; + $this->xdebug('used default namespace to make type ' . $attrs['type']); + } + } + // This is for constructs like + // <complexType name="ListOfString" base="soap:Array"> + // <sequence> + // <element name="string" type="xsd:string" + // minOccurs="0" maxOccurs="unbounded" /> + // </sequence> + // </complexType> + if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { + $this->xdebug('arrayType for unusual array is ' . $attrs['type']); + $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; + } + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $ename = $attrs['name']; + } elseif(isset($attrs['ref'])){ + $this->xdebug("processing element as ref to ".$attrs['ref']); + $this->currentElement = "ref to ".$attrs['ref']; + $ename = $this->getLocalPart($attrs['ref']); + } else { + $this->xdebug("processing untyped element ".$attrs['name']); + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; + $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; + $ename = $attrs['name']; + } + if(isset($ename) && $this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; + } + break; + case 'enumeration': // restriction value list member + $this->xdebug('enumeration ' . $attrs['value']); + if ($this->currentSimpleType) { + $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; + } elseif ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; + } + break; + case 'extension': // simpleContent or complexContent type extension + $this->xdebug('extension ' . $attrs['base']); + if ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; + } + break; + case 'import': + if (isset($attrs['schemaLocation'])) { + //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); + $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); + } else { + //$this->xdebug('import namespace ' . $attrs['namespace']); + $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + } + break; + case 'list': // simpleType value list + break; + case 'restriction': // simpleType, simpleContent or complexContent value restriction + $this->xdebug('restriction ' . $attrs['base']); + if($this->currentSimpleType){ + $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; + } elseif($this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; + if(strstr($attrs['base'],':') == ':Array'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } + } + break; + case 'schema': + $this->schemaInfo = $attrs; + $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); + if (isset($attrs['targetNamespace'])) { + $this->schemaTargetNamespace = $attrs['targetNamespace']; + } + if (!isset($attrs['elementFormDefault'])) { + $this->schemaInfo['elementFormDefault'] = 'unqualified'; + } + if (!isset($attrs['attributeFormDefault'])) { + $this->schemaInfo['attributeFormDefault'] = 'unqualified'; + } + break; + case 'simpleContent': // (optional) content for a complexType + break; + case 'simpleType': + array_push($this->simpleTypeStack, $this->currentSimpleType); + if(isset($attrs['name'])){ + $this->xdebug("processing simpleType for name " . $attrs['name']); + $this->currentSimpleType = $attrs['name']; + $this->simpleTypes[ $attrs['name'] ] = $attrs; + $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; + $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; + } else { + $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); + $this->currentSimpleType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->simpleTypes[$this->currentSimpleType] = $attrs; + $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; + } + break; + case 'union': // simpleType type list + break; + default: + //$this->xdebug("do not have anything to do for element $name"); + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function schemaEndElement($parser, $name) { + // bring depth down a notch + $this->depth--; + // position of current element is equal to the last value left in depth_array for my depth + if(isset($this->depth_array[$this->depth])){ + $pos = $this->depth_array[$this->depth]; + } + // get element prefix + if ($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + // move on... + if($name == 'complexType'){ + $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); + $this->currentComplexType = array_pop($this->complexTypeStack); + //$this->currentElement = false; + } + if($name == 'element'){ + $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); + $this->currentElement = array_pop($this->elementStack); + } + if($name == 'simpleType'){ + $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); + $this->currentSimpleType = array_pop($this->simpleTypeStack); + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function schemaCharacterData($parser, $data){ + $pos = $this->depth_array[$this->depth - 1]; + $this->message[$pos]['cdata'] .= $data; + } + + /** + * serialize the schema + * + * @access public + */ + function serializeSchema(){ + + $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); + $xml = ''; + // imports + if (sizeof($this->imports) > 0) { + foreach($this->imports as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; + } else { + $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; + } + } + } + } + // complex types + foreach($this->complexTypes as $typeName => $attrs){ + $contentStr = ''; + // serialize child elements + if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ + foreach($attrs['elements'] as $element => $eParts){ + if(isset($eParts['ref'])){ + $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; + } else { + $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; + foreach ($eParts as $aName => $aValue) { + // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable + if ($aName != 'name' && $aName != 'type') { + $contentStr .= " $aName=\"$aValue\""; + } + } + $contentStr .= "/>\n"; + } + } + // compositor wraps elements + if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { + $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n"; + } + } + // attributes + if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ + foreach($attrs['attrs'] as $attr => $aParts){ + $contentStr .= " <$schemaPrefix:attribute"; + foreach ($aParts as $a => $v) { + if ($a == 'ref' || $a == 'type') { + $contentStr .= " $a=\"".$this->contractQName($v).'"'; + } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { + $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; + $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; + } else { + $contentStr .= " $a=\"$v\""; + } + } + $contentStr .= "/>\n"; + } + } + // if restriction + if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ + $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n"; + // complex or simple content + if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ + $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n"; + } + } + // finalize complex type + if($contentStr != ''){ + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n"; + } else { + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; + } + $xml .= $contentStr; + } + // simple types + if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ + foreach($this->simpleTypes as $typeName => $eParts){ + $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; + if (isset($eParts['enumeration'])) { + foreach ($eParts['enumeration'] as $e) { + $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; + } + } + $xml .= " </$schemaPrefix:simpleType>"; + } + } + // elements + if(isset($this->elements) && count($this->elements) > 0){ + foreach($this->elements as $element => $eParts){ + $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; + } + } + // attributes + if(isset($this->attributes) && count($this->attributes) > 0){ + foreach($this->attributes as $attr => $aParts){ + $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; + } + } + // finish 'er up + $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; + foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { + $el .= " xmlns:$nsp=\"$ns\"\n"; + } + $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n"; + return $xml; + } + + /** + * adds debug data to the clas level debug string + * + * @param string $string debug data + * @access private + */ + function xdebug($string){ + $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); + } + + /** + * get the PHP type of a user defined type in the schema + * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays + * returns false if no type exists, or not w/ the given namespace + * else returns a string that is either a native php type, or 'struct' + * + * @param string $type, name of defined type + * @param string $ns, namespace of type + * @return mixed + * @access public + * @deprecated + */ + function getPHPType($type,$ns){ + if(isset($this->typemap[$ns][$type])){ + //print "found type '$type' and ns $ns in typemap<br>"; + return $this->typemap[$ns][$type]; + } elseif(isset($this->complexTypes[$type])){ + //print "getting type '$type' and ns $ns from complexTypes array<br>"; + return $this->complexTypes[$type]['phpType']; + } + return false; + } + + /** + * returns an associative array of information about a given type + * returns false if no type exists by the given name + * + * For a complexType typeDef = array( + * 'restrictionBase' => '', + * 'phpType' => '', + * 'compositor' => '(sequence|all)', + * 'elements' => array(), // refs to elements array + * 'attrs' => array() // refs to attributes array + * ... and so on (see addComplexType) + * ) + * + * For simpleType or element, the array has different keys. + * + * @param string + * @return mixed + * @access public + * @see addComplexType + * @see addSimpleType + * @see addElement + */ + function getTypeDef($type){ + //$this->debug("in getTypeDef for type $type"); + if(isset($this->complexTypes[$type])){ + $this->xdebug("in getTypeDef, found complexType $type"); + return $this->complexTypes[$type]; + } elseif(isset($this->simpleTypes[$type])){ + $this->xdebug("in getTypeDef, found simpleType $type"); + if (!isset($this->simpleTypes[$type]['phpType'])) { + // get info for type to tack onto the simple type + // TODO: can this ever really apply (i.e. what is a simpleType really?) + $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); + $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for simpleType $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->simpleTypes[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->simpleTypes[$type]['elements'] = $etype['elements']; + } + } + } + return $this->simpleTypes[$type]; + } elseif(isset($this->elements[$type])){ + $this->xdebug("in getTypeDef, found element $type"); + if (!isset($this->elements[$type]['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); + $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for element $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->elements[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->elements[$type]['elements'] = $etype['elements']; + } + } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { + $this->xdebug("in getTypeDef, element $type is an XSD type"); + $this->elements[$type]['phpType'] = 'scalar'; + } + } + return $this->elements[$type]; + } elseif(isset($this->attributes[$type])){ + $this->xdebug("in getTypeDef, found attribute $type"); + return $this->attributes[$type]; + } elseif (ereg('_ContainedType$', $type)) { + $this->xdebug("in getTypeDef, have an untyped element $type"); + $typeDef['typeClass'] = 'simpleType'; + $typeDef['phpType'] = 'scalar'; + $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; + return $typeDef; + } + $this->xdebug("in getTypeDef, did not find $type"); + return false; + } + + /** + * returns a sample serialization of a given type, or false if no type by the given name + * + * @param string $type, name of type + * @return mixed + * @access public + * @deprecated + */ + function serializeTypeDef($type){ + //print "in sTD() for type $type<br>"; + if($typeDef = $this->getTypeDef($type)){ + $str .= '<'.$type; + if(is_array($typeDef['attrs'])){ + foreach($attrs as $attName => $data){ + $str .= " $attName=\"{type = ".$data['type']."}\""; + } + } + $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; + if(count($typeDef['elements']) > 0){ + $str .= ">"; + foreach($typeDef['elements'] as $element => $eData){ + $str .= $this->serializeTypeDef($element); + } + $str .= "</$type>"; + } elseif($typeDef['typeClass'] == 'element') { + $str .= "></$type>"; + } else { + $str .= "/>"; + } + return $str; + } + return false; + } + + /** + * returns HTML form elements that allow a user + * to enter values for creating an instance of the given type. + * + * @param string $name, name for type instance + * @param string $type, name of type + * @return string + * @access public + * @deprecated + */ + function typeToForm($name,$type){ + // get typedef + if($typeDef = $this->getTypeDef($type)){ + // if struct + if($typeDef['phpType'] == 'struct'){ + $buffer .= '<table>'; + foreach($typeDef['elements'] as $child => $childDef){ + $buffer .= " + <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td> + <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>"; + } + $buffer .= '</table>'; + // if array + } elseif($typeDef['phpType'] == 'array'){ + $buffer .= '<table>'; + for($i=0;$i < 3; $i++){ + $buffer .= " + <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> + <td><input type='text' name='parameters[".$name."][]'></td></tr>"; + } + $buffer .= '</table>'; + // if scalar + } else { + $buffer .= "<input type='text' name='parameters[$name]'>"; + } + } else { + $buffer .= "<input type='text' name='parameters[$name]'>"; + } + return $buffer; + } + + /** + * adds a complex type to the schema + * + * example: array + * + * addType( + * 'ArrayOfstring', + * 'complexType', + * 'array', + * '', + * 'SOAP-ENC:Array', + * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), + * 'xsd:string' + * ); + * + * example: PHP associative array ( SOAP Struct ) + * + * addType( + * 'SOAPStruct', + * 'complexType', + * 'struct', + * 'all', + * array('myVar'=> array('name'=>'myVar','type'=>'string') + * ); + * + * @param name + * @param typeClass (complexType|simpleType|attribute) + * @param phpType: currently supported are array and struct (php assoc array) + * @param compositor (all|sequence|choice) + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param elements = array ( name = array(name=>'',type=>'') ) + * @param attrs = array( + * array( + * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", + * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" + * ) + * ) + * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) + * @access public + * @see getTypeDef + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ + $this->complexTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'compositor'=> $compositor, + 'restrictionBase' => $restrictionBase, + 'elements' => $elements, + 'attrs' => $attrs, + 'arrayType' => $arrayType + ); + + $this->xdebug("addComplexType $name:"); + $this->appendDebug($this->varDump($this->complexTypes[$name])); + } + + /** + * adds a simple type to the schema + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @access public + * @see xmlschema + * @see getTypeDef + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $this->simpleTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'type' => $restrictionBase, + 'enumeration' => $enumeration + ); + + $this->xdebug("addSimpleType $name:"); + $this->appendDebug($this->varDump($this->simpleTypes[$name])); + } + + /** + * adds an element to the schema + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + if (! $this->getPrefix($attrs['type'])) { + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; + } + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + + $this->xdebug("addElement " . $attrs['name']); + $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); + } +} + + + +?><?php + + + +/** +* For creating serializable abstractions of native PHP types. This class +* allows element name/namespace, XSD type, and XML attributes to be +* associated with a value. This is extremely useful when WSDL is not +* used, but is also useful when WSDL is used with polymorphic types, including +* xsd:anyType and user-defined types. +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soapval extends nusoap_base { + /** + * The XML element name + * + * @var string + * @access private + */ + var $name; + /** + * The XML type name (string or false) + * + * @var mixed + * @access private + */ + var $type; + /** + * The PHP value + * + * @var mixed + * @access private + */ + var $value; + /** + * The XML element namespace (string or false) + * + * @var mixed + * @access private + */ + var $element_ns; + /** + * The XML type namespace (string or false) + * + * @var mixed + * @access private + */ + var $type_ns; + /** + * The XML element attributes (array or false) + * + * @var mixed + * @access private + */ + var $attributes; + + /** + * constructor + * + * @param string $name optional name + * @param mixed $type optional type name + * @param mixed $value optional value + * @param mixed $element_ns optional namespace of value + * @param mixed $type_ns optional namespace of type + * @param mixed $attributes associative array of attributes to add to element serialization + * @access public + */ + function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { + parent::nusoap_base(); + $this->name = $name; + $this->type = $type; + $this->value = $value; + $this->element_ns = $element_ns; + $this->type_ns = $type_ns; + $this->attributes = $attributes; + } + + /** + * return serialized value + * + * @param string $use The WSDL use value (encoded|literal) + * @return string XML data + * @access public + */ + function serialize($use='encoded') { + return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); + } + + /** + * decodes a soapval object into a PHP native type + * + * @return mixed + * @access public + */ + function decode(){ + return $this->value; + } +} + + + +?><?php + + + +/** +* transport class for sending/receiving data via HTTP and HTTPS +* NOTE: PHP must be compiled with the CURL extension for HTTPS support +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_transport_http extends nusoap_base { + + var $url = ''; + var $uri = ''; + var $digest_uri = ''; + var $scheme = ''; + var $host = ''; + var $port = ''; + var $path = ''; + var $request_method = 'POST'; + var $protocol_version = '1.0'; + var $encoding = ''; + var $outgoing_headers = array(); + var $incoming_headers = array(); + var $incoming_cookies = array(); + var $outgoing_payload = ''; + var $incoming_payload = ''; + var $useSOAPAction = true; + var $persistentConnection = false; + var $ch = false; // cURL handle + var $username = ''; + var $password = ''; + var $authtype = ''; + var $digestRequest = array(); + var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) + // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' + // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' + // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' + // passphrase: SSL key password/passphrase + // verifypeer: default is 1 + // verifyhost: default is 1 + + /** + * constructor + */ + function soap_transport_http($url){ + parent::nusoap_base(); + $this->setURL($url); + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; + $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); + } + + function setURL($url) { + $this->url = $url; + + $u = parse_url($url); + foreach($u as $k => $v){ + $this->debug("$k = $v"); + $this->$k = $v; + } + + // add any GET params to path + if(isset($u['query']) && $u['query'] != ''){ + $this->path .= '?' . $u['query']; + } + + // set default port + if(!isset($u['port'])){ + if($u['scheme'] == 'https'){ + $this->port = 443; + } else { + $this->port = 80; + } + } + + $this->uri = $this->path; + $this->digest_uri = $this->uri; + + // build headers + if (!isset($u['port'])) { + $this->outgoing_headers['Host'] = $this->host; + } else { + $this->outgoing_headers['Host'] = $this->host.':'.$this->port; + } + $this->debug('set Host: ' . $this->outgoing_headers['Host']); + + if (isset($u['user']) && $u['user'] != '') { + $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); + } + } + + function connect($connection_timeout=0,$response_timeout=30){ + // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like + // "regular" socket. + // TODO: disabled for now because OpenSSL must be *compiled* in (not just + // loaded), and until PHP5 stream_get_wrappers is not available. +// if ($this->scheme == 'https') { +// if (version_compare(phpversion(), '4.3.0') >= 0) { +// if (extension_loaded('openssl')) { +// $this->scheme = 'ssl'; +// $this->debug('Using SSL over OpenSSL'); +// } +// } +// } + $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // use persistent connection + if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ + if (!feof($this->fp)) { + $this->debug('Re-use persistent connection'); + return true; + } + fclose($this->fp); + $this->debug('Closed persistent connection at EOF'); + } + + // munge host if using OpenSSL + if ($this->scheme == 'ssl') { + $host = 'ssl://' . $this->host; + } else { + $host = $this->host; + } + $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); + + // open socket + if($connection_timeout > 0){ + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); + } else { + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); + } + + // test pointer + if(!$this->fp) { + $msg = 'Couldn\'t open socket connection to server ' . $this->url; + if ($this->errno) { + $msg .= ', Error ('.$this->errno.'): '.$this->error_str; + } else { + $msg .= ' prior to connect(). This is often a problem looking up the host name.'; + } + $this->debug($msg); + $this->setError($msg); + return false; + } + + // set response timeout + $this->debug('set response timeout to ' . $response_timeout); + socket_set_timeout( $this->fp, $response_timeout); + + $this->debug('socket connected'); + return true; + } else if ($this->scheme == 'https') { + if (!extension_loaded('curl')) { + $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); + return false; + } + $this->debug('connect using https'); + // init CURL + $this->ch = curl_init(); + // set url + $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; + // add path + $hostURL .= $this->path; + curl_setopt($this->ch, CURLOPT_URL, $hostURL); + // follow location headers (re-directs) + curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); + // ask for headers in the response output + curl_setopt($this->ch, CURLOPT_HEADER, 1); + // ask for the response output as the return value + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); + // encode + // We manage this ourselves through headers and encoding +// if(function_exists('gzuncompress')){ +// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); +// } + // persistent connection + if ($this->persistentConnection) { + // The way we send data, we cannot use persistent connections, since + // there will be some "junk" at the end of our request. + //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); + $this->persistentConnection = false; + $this->outgoing_headers['Connection'] = 'close'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + // set timeout + if ($connection_timeout != 0) { + curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); + } + // TODO: cURL has added a connection timeout separate from the response timeout + //if ($connection_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); + //} + //if ($response_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); + //} + + // recent versions of cURL turn on peer/host checking by default, + // while PHP binaries are not compiled with a default location for the + // CA cert bundle, so disable peer/host checking. +//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); + + // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) + if ($this->authtype == 'certificate') { + if (isset($this->certRequest['cainfofile'])) { + curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); + } + if (isset($this->certRequest['verifypeer'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); + } + if (isset($this->certRequest['verifyhost'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); + } + if (isset($this->certRequest['sslcertfile'])) { + curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); + } + if (isset($this->certRequest['sslkeyfile'])) { + curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); + } + if (isset($this->certRequest['passphrase'])) { + curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); + } + } + $this->debug('cURL connection set up'); + return true; + } else { + $this->setError('Unknown scheme ' . $this->scheme); + $this->debug('Unknown scheme ' . $this->scheme); + return false; + } + } + + /** + * send the SOAP message via HTTP + * + * @param string $data message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { + + $this->debug('entered send() with data of length: '.strlen($data)); + + $this->tryagain = true; + $tries = 0; + while ($this->tryagain) { + $this->tryagain = false; + if ($tries++ < 2) { + // make connnection + if (!$this->connect($timeout, $response_timeout)){ + return false; + } + + // send request + if (!$this->sendRequest($data, $cookies)){ + return false; + } + + // get response + $respdata = $this->getResponse(); + } else { + $this->setError('Too many tries to get an OK response'); + } + } + $this->debug('end of send()'); + return $respdata; + } + + + /** + * send the SOAP message via HTTPS 1.0 using CURL + * + * @param string $msg message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { + return $this->send($data, $timeout, $response_timeout, $cookies); + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic, digest, certificate) + * @param array $digestRequest (keys must be nonce, nc, realm, qop) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { + $this->debug("Set credentials for authtype $authtype"); + // cf. RFC 2617 + if ($authtype == 'basic') { + $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); + } elseif ($authtype == 'digest') { + if (isset($digestRequest['nonce'])) { + $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; + + // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) + + // A1 = unq(username-value) ":" unq(realm-value) ":" passwd + $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; + + // H(A1) = MD5(A1) + $HA1 = md5($A1); + + // A2 = Method ":" digest-uri-value + $A2 = 'POST:' . $this->digest_uri; + + // H(A2) + $HA2 = md5($A2); + + // KD(secret, data) = H(concat(secret, ":", data)) + // if qop == auth: + // request-digest = <"> < KD ( H(A1), unq(nonce-value) + // ":" nc-value + // ":" unq(cnonce-value) + // ":" unq(qop-value) + // ":" H(A2) + // ) <"> + // if qop is missing, + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> + + $unhashedDigest = ''; + $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; + $cnonce = $nonce; + if ($digestRequest['qop'] != '') { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; + } else { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; + } + + $hashedDigest = md5($unhashedDigest); + + $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; + } + } elseif ($authtype == 'certificate') { + $this->certRequest = $certRequest; + } + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->digestRequest = $digestRequest; + + if (isset($this->outgoing_headers['Authorization'])) { + $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); + } else { + $this->debug('Authorization header not set'); + } + } + + /** + * set the soapaction value + * + * @param string $soapaction + * @access public + */ + function setSOAPAction($soapaction) { + $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; + $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); + } + + /** + * use http encoding + * + * @param string $enc encoding style. supported values: gzip, deflate, or both + * @access public + */ + function setEncoding($enc='gzip, deflate') { + if (function_exists('gzdeflate')) { + $this->protocol_version = '1.1'; + $this->outgoing_headers['Accept-Encoding'] = $enc; + $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); + if (!isset($this->outgoing_headers['Connection'])) { + $this->outgoing_headers['Connection'] = 'close'; + $this->persistentConnection = false; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + set_magic_quotes_runtime(0); + // deprecated + $this->encoding = $enc; + } + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->uri = $this->url; + $this->host = $proxyhost; + $this->port = $proxyport; + if ($proxyusername != '' && $proxypassword != '') { + $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); + $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); + } + } + + /** + * decode a string that is encoded w/ "chunked' transfer encoding + * as defined in RFC2068 19.4.6 + * + * @param string $buffer + * @param string $lb + * @returns string + * @access public + * @deprecated + */ + function decodeChunked($buffer, $lb){ + // length := 0 + $length = 0; + $new = ''; + + // read chunk-size, chunk-extension (if any) and CRLF + // get the position of the linebreak + $chunkend = strpos($buffer, $lb); + if ($chunkend == FALSE) { + $this->debug('no linebreak found in decodeChunked'); + return $new; + } + $temp = substr($buffer,0,$chunkend); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend + strlen($lb); + // while (chunk-size > 0) { + while ($chunk_size > 0) { + $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); + $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); + + // Just in case we got a broken connection + if ($chunkend == FALSE) { + $chunk = substr($buffer,$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + $length += strlen($chunk); + break; + } + + // read chunk-data and CRLF + $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + // length := length + chunk-size + $length += strlen($chunk); + // read chunk-size and CRLF + $chunkstart = $chunkend + strlen($lb); + + $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); + if ($chunkend == FALSE) { + break; //Just in case we got a broken connection + } + $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend; + } + return $new; + } + + /* + * Writes payload, including HTTP headers, to $this->outgoing_payload. + */ + function buildPayload($data, $cookie_str = '') { + // add content-length header + $this->outgoing_headers['Content-Length'] = strlen($data); + $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); + + // start building outgoing payload: + $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; + $this->debug("HTTP request: $req"); + $this->outgoing_payload = "$req\r\n"; + + // loop thru headers, serializing + foreach($this->outgoing_headers as $k => $v){ + $hdr = $k.': '.$v; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // add any cookies + if ($cookie_str != '') { + $hdr = 'Cookie: '.$cookie_str; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // header/body separator + $this->outgoing_payload .= "\r\n"; + + // add data + $this->outgoing_payload .= $data; + } + + function sendRequest($data, $cookies = NULL) { + // build cookie string + $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); + + // build payload + $this->buildPayload($data, $cookie_str); + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // send payload + if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { + $this->setError('couldn\'t write message data to socket'); + $this->debug('couldn\'t write message data to socket'); + return false; + } + $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); + return true; + } else if ($this->scheme == 'https') { + // set payload + // TODO: cURL does say this should only be the verb, and in fact it + // turns out that the URI and HTTP version are appended to this, which + // some servers refuse to work with + //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); + foreach($this->outgoing_headers as $k => $v){ + $curl_headers[] = "$k: $v"; + } + if ($cookie_str != '') { + $curl_headers[] = 'Cookie: ' . $cookie_str; + } + curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); + if ($this->request_method == "POST") { + curl_setopt($this->ch, CURLOPT_POST, 1); + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); + } else { + } + $this->debug('set cURL payload'); + return true; + } + } + + function getResponse(){ + $this->incoming_payload = ''; + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // loop until headers have been retrieved + $data = ''; + while (!isset($lb)){ + + // We might EOF during header read. + if(feof($this->fp)) { + $this->incoming_payload = $data; + $this->debug('found no headers before EOF after length ' . strlen($data)); + $this->debug("received before EOF:\n" . $data); + $this->setError('server failed to send headers'); + return false; + } + + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read line of $tmplen bytes: " . trim($tmp)); + + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of headers timed out after length ' . strlen($data)); + $this->debug("read before timeout: " . $data); + $this->setError('socket read of headers timed out'); + return false; + } + + $data .= $tmp; + $pos = strpos($data,"\r\n\r\n"); + if($pos > 1){ + $lb = "\r\n"; + } else { + $pos = strpos($data,"\n\n"); + if($pos > 1){ + $lb = "\n"; + } + } + // remove 100 header + if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ + unset($lb); + $data = ''; + }// + } + // store header data + $this->incoming_payload .= $data; + $this->debug('found end of headers after length ' . strlen($data)); + // process headers + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $this->incoming_headers = array(); + $this->incoming_cookies = array(); + foreach($header_array as $header_line){ + $arr = explode(':',$header_line, 2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + + // loop until msg has been received + if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { + $content_length = 2147483647; // ignore any content-length header + $chunked = true; + $this->debug("want to read chunked content"); + } elseif (isset($this->incoming_headers['content-length'])) { + $content_length = $this->incoming_headers['content-length']; + $chunked = false; + $this->debug("want to read content of length $content_length"); + } else { + $content_length = 2147483647; + $chunked = false; + $this->debug("want to read content to EOF"); + } + $data = ''; + do { + if ($chunked) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk line of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk length timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk length timed out'); + return false; + } + $content_length = hexdec(trim($tmp)); + $this->debug("chunk length $content_length"); + } + $strlen = 0; + while (($strlen < $content_length) && (!feof($this->fp))) { + $readlen = min(8192, $content_length - $strlen); + $tmp = fread($this->fp, $readlen); + $tmplen = strlen($tmp); + $this->debug("read buffer of $tmplen bytes"); + if (($tmplen == 0) && (!feof($this->fp))) { + $this->incoming_payload = $data; + $this->debug('socket read of body timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of body timed out'); + return false; + } + $strlen += $tmplen; + $data .= $tmp; + } + if ($chunked && ($content_length > 0)) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk terminator of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk terminator timed out'); + return false; + } + } + } while ($chunked && ($content_length > 0) && (!feof($this->fp))); + if (feof($this->fp)) { + $this->debug('read to EOF'); + } + $this->debug('read body of length ' . strlen($data)); + $this->incoming_payload .= $data; + $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); + + // close filepointer + if( + (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || + (! $this->persistentConnection) || feof($this->fp)){ + fclose($this->fp); + $this->fp = false; + $this->debug('closed socket'); + } + + // connection was closed unexpectedly + if($this->incoming_payload == ''){ + $this->setError('no response from server'); + return false; + } + + // decode transfer-encoding +// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ +// if(!$data = $this->decodeChunked($data, $lb)){ +// $this->setError('Decoding of chunked data failed'); +// return false; +// } + //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>"; + // set decoded payload +// $this->incoming_payload = $header_data.$lb.$lb.$data; +// } + + } else if ($this->scheme == 'https') { + // send and receive + $this->debug('send and receive with cURL'); + $this->incoming_payload = curl_exec($this->ch); + $data = $this->incoming_payload; + + $cErr = curl_error($this->ch); + if ($cErr != '') { + $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>'; + // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE + foreach(curl_getinfo($this->ch) as $k => $v){ + $err .= "$k: $v<br>"; + } + $this->debug($err); + $this->setError($err); + curl_close($this->ch); + return false; + } else { + //echo '<pre>'; + //var_dump(curl_getinfo($this->ch)); + //echo '</pre>'; + } + // close curl + $this->debug('No cURL error, closing cURL'); + curl_close($this->ch); + + // remove 100 header(s) + while (ereg('^HTTP/1.1 100',$data)) { + if ($pos = strpos($data,"\r\n\r\n")) { + $data = ltrim(substr($data,$pos)); + } elseif($pos = strpos($data,"\n\n") ) { + $data = ltrim(substr($data,$pos)); + } + } + + // separate content from HTTP headers + if ($pos = strpos($data,"\r\n\r\n")) { + $lb = "\r\n"; + } elseif( $pos = strpos($data,"\n\n")) { + $lb = "\n"; + } else { + $this->debug('no proper separation of headers and document'); + $this->setError('no proper separation of headers and document'); + return false; + } + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $data = ltrim(substr($data,$pos)); + $this->debug('found proper separation of headers and document'); + $this->debug('cleaned data, stringlen: '.strlen($data)); + // clean headers + foreach ($header_array as $header_line) { + $arr = explode(':',$header_line,2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + } + + $arr = explode(' ', $header_array[0], 3); + $http_version = $arr[0]; + $http_status = intval($arr[1]); + $http_reason = count($arr) > 2 ? $arr[2] : ''; + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['location']) && $http_status == 301) { + $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); + $this->setURL($this->incoming_headers['location']); + $this->tryagain = true; + return false; + } + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { + $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); + if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { + $this->debug('Server wants digest authentication'); + // remove "Digest " from our elements + $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); + + // parse elements into array + $digestElements = explode(',', $digestString); + foreach ($digestElements as $val) { + $tempElement = explode('=', trim($val), 2); + $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); + } + + // should have (at least) qop, realm, nonce + if (isset($digestRequest['nonce'])) { + $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); + $this->tryagain = true; + return false; + } + } + $this->debug('HTTP authentication failed'); + $this->setError('HTTP authentication failed'); + return false; + } + + if ( + ($http_status >= 300 && $http_status <= 307) || + ($http_status >= 400 && $http_status <= 417) || + ($http_status >= 501 && $http_status <= 505) + ) { + $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); + return false; + } + + // decode content-encoding + if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ + if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ + // if decoding works, use it. else assume data wasn't gzencoded + if(function_exists('gzinflate')){ + //$timer->setMarker('starting decoding of gzip/deflated content'); + // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) + // this means there are no Zlib headers, although there should be + $this->debug('The gzinflate function exists'); + $datalen = strlen($data); + if ($this->incoming_headers['content-encoding'] == 'deflate') { + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The inflated payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to inflate the payload'); + $this->setError('Error using gzinflate to inflate the payload'); + } + } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { + if ($degzdata = @gzinflate(substr($data, 10))) { // do our best + $data = $degzdata; + $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate(substr($data, 10))) { + $data = $degzdata; + $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to un-gzip the payload'); + $this->setError('Error using gzinflate to un-gzip the payload'); + } + } + //$timer->setMarker('finished decoding of gzip/deflated content'); + //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>"; + // set decoded payload + $this->incoming_payload = $header_data.$lb.$lb.$data; + } else { + $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + } + } else { + $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + } + } else { + $this->debug('No Content-Encoding header'); + } + + if(strlen($data) == 0){ + $this->debug('no data after headers!'); + $this->setError('no data present after HTTP headers'); + return false; + } + + return $data; + } + + function setContentType($type, $charset = false) { + $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); + $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); + } + + function usePersistentConnection(){ + if (isset($this->outgoing_headers['Accept-Encoding'])) { + return false; + } + $this->protocol_version = '1.1'; + $this->persistentConnection = true; + $this->outgoing_headers['Connection'] = 'Keep-Alive'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + return true; + } + + /** + * parse an incoming Cookie into it's parts + * + * @param string $cookie_str content of cookie + * @return array with data of that cookie + * @access private + */ + /* + * TODO: allow a Set-Cookie string to be parsed into multiple cookies + */ + function parseCookie($cookie_str) { + $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; + $data = split(';', $cookie_str); + $value_str = $data[0]; + + $cookie_param = 'domain='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $domain = substr($cookie_str, $start + strlen($cookie_param)); + $domain = substr($domain, 0, strpos($domain, ';')); + } else { + $domain = ''; + } + + $cookie_param = 'expires='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $expires = substr($cookie_str, $start + strlen($cookie_param)); + $expires = substr($expires, 0, strpos($expires, ';')); + } else { + $expires = ''; + } + + $cookie_param = 'path='; + $start = strpos($cookie_str, $cookie_param); + if ( $start > 0 ) { + $path = substr($cookie_str, $start + strlen($cookie_param)); + $path = substr($path, 0, strpos($path, ';')); + } else { + $path = '/'; + } + + $cookie_param = ';secure;'; + if (strpos($cookie_str, $cookie_param) !== FALSE) { + $secure = true; + } else { + $secure = false; + } + + $sep_pos = strpos($value_str, '='); + + if ($sep_pos) { + $name = substr($value_str, 0, $sep_pos); + $value = substr($value_str, $sep_pos + 1); + $cookie= array( 'name' => $name, + 'value' => $value, + 'domain' => $domain, + 'path' => $path, + 'expires' => $expires, + 'secure' => $secure + ); + return $cookie; + } + return false; + } + + /** + * sort out cookies for the current request + * + * @param array $cookies array with all cookies + * @param boolean $secure is the send-content secure or not? + * @return string for Cookie-HTTP-Header + * @access private + */ + function getCookiesForRequest($cookies, $secure=false) { + $cookie_str = ''; + if ((! is_null($cookies)) && (is_array($cookies))) { + foreach ($cookies as $cookie) { + if (! is_array($cookie)) { + continue; + } + $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) <= time()) { + $this->debug('cookie has expired'); + continue; + } + } + if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { + $domain = preg_quote($cookie['domain']); + if (! preg_match("'.*$domain$'i", $this->host)) { + $this->debug('cookie has different domain'); + continue; + } + } + if ((isset($cookie['path'])) && (! empty($cookie['path']))) { + $path = preg_quote($cookie['path']); + if (! preg_match("'^$path.*'i", $this->path)) { + $this->debug('cookie is for a different path'); + continue; + } + } + if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { + $this->debug('cookie is secure, transport is not'); + continue; + } + $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; + $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); + } + } + return $cookie_str; + } +} + +?><?php + + + +/** +* +* soap_server allows the user to create a SOAP server +* that is capable of receiving messages and returning responses +* +* NOTE: WSDL functionality is experimental +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_server extends nusoap_base { + /** + * HTTP headers of request + * @var array + * @access private + */ + var $headers = array(); + /** + * HTTP request + * @var string + * @access private + */ + var $request = ''; + /** + * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $requestHeaders = ''; + /** + * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $document = ''; + /** + * SOAP payload for request (text) + * @var string + * @access public + */ + var $requestSOAP = ''; + /** + * requested method namespace URI + * @var string + * @access private + */ + var $methodURI = ''; + /** + * name of method requested + * @var string + * @access private + */ + var $methodname = ''; + /** + * method parameters from request + * @var array + * @access private + */ + var $methodparams = array(); + /** + * SOAP Action from request + * @var string + * @access private + */ + var $SOAPAction = ''; + /** + * character set encoding of incoming (request) messages + * @var string + * @access public + */ + var $xml_encoding = ''; + /** + * toggles whether the parser decodes element content w/ utf8_decode() + * @var boolean + * @access public + */ + var $decode_utf8 = true; + + /** + * HTTP headers of response + * @var array + * @access public + */ + var $outgoing_headers = array(); + /** + * HTTP response + * @var string + * @access private + */ + var $response = ''; + /** + * SOAP headers for response (text) + * @var string + * @access public + */ + var $responseHeaders = ''; + /** + * SOAP payload for response (text) + * @var string + * @access private + */ + var $responseSOAP = ''; + /** + * method return value to place in response + * @var mixed + * @access private + */ + var $methodreturn = false; + /** + * whether $methodreturn is a string of literal XML + * @var boolean + * @access public + */ + var $methodreturnisliteralxml = false; + /** + * SOAP fault for response (or false) + * @var mixed + * @access private + */ + var $fault = false; + /** + * text indication of result (for debugging) + * @var string + * @access private + */ + var $result = 'successful'; + + /** + * assoc array of operations => opData; operations are added by the register() + * method or by parsing an external WSDL definition + * @var array + * @access private + */ + var $operations = array(); + /** + * wsdl instance (if one) + * @var mixed + * @access private + */ + var $wsdl = false; + /** + * URL for WSDL (if one) + * @var mixed + * @access private + */ + var $externalWSDLURL = false; + /** + * whether to append debug to response as XML comment + * @var boolean + * @access public + */ + var $debug_flag = false; + + + /** + * constructor + * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. + * + * @param mixed $wsdl file path or URL (string), or wsdl instance (object) + * @access public + */ + function soap_server($wsdl=false){ + parent::nusoap_base(); + // turn on debugging? + global $debug; + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $this->debug("_SERVER is defined:"); + $this->appendDebug($this->varDump($_SERVER)); + } elseif (isset($HTTP_SERVER_VARS)) { + $this->debug("HTTP_SERVER_VARS is defined:"); + $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); + } else { + $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); + } + + if (isset($debug)) { + $this->debug("In soap_server, set debug_flag=$debug based on global flag"); + $this->debug_flag = $debug; + } elseif (isset($_SERVER['QUERY_STRING'])) { + $qs = explode('&', $_SERVER['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); + $this->debug_flag = substr($v, 6); + } + } + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); + $this->debug_flag = substr($v, 6); + } + } + } + + // wsdl + if($wsdl){ + $this->debug("In soap_server, WSDL is specified"); + if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { + $this->wsdl = $wsdl; + $this->externalWSDLURL = $this->wsdl->wsdl; + $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); + } else { + $this->debug('Create wsdl from ' . $wsdl); + $this->wsdl = new wsdl($wsdl); + $this->externalWSDLURL = $wsdl; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($err = $this->wsdl->getError()){ + die('WSDL ERROR: '.$err); + } + } + } + + /** + * processes request and returns response + * + * @param string $data usually is the value of $HTTP_RAW_POST_DATA + * @access public + */ + function service($data){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER['QUERY_STRING'])) { + $qs = $_SERVER['QUERY_STRING']; + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = $HTTP_SERVER_VARS['QUERY_STRING']; + } else { + $qs = ''; + } + $this->debug("In service, query string=$qs"); + + if (ereg('wsdl', $qs) ){ + $this->debug("In service, this is a request for WSDL"); + if($this->externalWSDLURL){ + if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL + header('Location: '.$this->externalWSDLURL); + } else { // assume file + header("Content-Type: text/xml\r\n"); + $fp = fopen($this->externalWSDLURL, 'r'); + fpassthru($fp); + } + } elseif ($this->wsdl) { + header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); + print $this->wsdl->serialize($this->debug_flag); + if ($this->debug_flag) { + $this->debug('wsdl:'); + $this->appendDebug($this->varDump($this->wsdl)); + print $this->getDebugAsXMLComment(); + } + } else { + header("Content-Type: text/html; charset=ISO-8859-1\r\n"); + print "This service does not provide WSDL"; + } + } elseif ($data == '' && $this->wsdl) { + $this->debug("In service, there is no data, so return Web description"); + print $this->wsdl->webDescription(); + } else { + $this->debug("In service, invoke the request"); + $this->parse_request($data); + if (! $this->fault) { + $this->invoke_method(); + } + if (! $this->fault) { + $this->serialize_return(); + } + $this->send_response(); + } + } + + /** + * parses HTTP request headers. + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * + * @access private + */ + function parse_http_headers() { + global $HTTP_SERVER_VARS; + + $this->request = ''; + $this->SOAPAction = ''; + if(function_exists('getallheaders')){ + $this->debug("In parse_http_headers, use getallheaders"); + $headers = getallheaders(); + foreach($headers as $k=>$v){ + $k = strtolower($k); + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + // get SOAPAction header + if(isset($this->headers['soapaction'])){ + $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); + } + // get the character encoding of the incoming request + if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ + $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } elseif(isset($_SERVER) && is_array($_SERVER)){ + $this->debug("In parse_http_headers, use _SERVER"); + foreach ($_SERVER as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } elseif (is_array($HTTP_SERVER_VARS)) { + $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); + foreach ($HTTP_SERVER_VARS as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } else { + $this->debug("In parse_http_headers, HTTP headers not accessible"); + $this->setError("HTTP headers not accessible"); + } + } + + /** + * parses a request + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * request + * requestSOAP + * methodURI + * methodname + * methodparams + * requestHeaders + * document + * + * This sets the fault field on error + * + * @param string $data XML string + * @access private + */ + function parse_request($data='') { + $this->debug('entering parse_request()'); + $this->parse_http_headers(); + $this->debug('got character encoding: '.$this->xml_encoding); + // uncompress if necessary + if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { + $this->debug('got content encoding: ' . $this->headers['content-encoding']); + if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { + // if decoding works, use it. else assume data wasn't gzencoded + if (function_exists('gzuncompress')) { + if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { + $data = $degzdata; + } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { + $data = $degzdata; + } else { + $this->fault('Client', 'Errors occurred when trying to decode the data'); + return; + } + } else { + $this->fault('Client', 'This Server does not support compressed data'); + return; + } + } + } + $this->request .= "\r\n".$data; + $data = $this->parseRequest($this->headers, $data); + $this->requestSOAP = $data; + $this->debug('leaving parse_request'); + } + + /** + * invokes a PHP function for the requested SOAP method + * + * The following fields are set by this function (when successful) + * + * methodreturn + * + * Note that the PHP function that is called may also set the following + * fields to affect the response sent to the client + * + * responseHeaders + * outgoing_headers + * + * This sets the fault field on error + * + * @access private + */ + function invoke_method() { + $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); + + if ($this->wsdl) { + if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { + $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { + // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element + $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + $this->methodname = $this->opData['name']; + } else { + $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); + $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); + return; + } + } else { + $this->debug('in invoke_method, no WSDL to validate method'); + } + + // if a . is present in $this->methodname, we see if there is a class in scope, + // which could be referred to. We will also distinguish between two deliminators, + // to allow methods to be called a the class or an instance + $class = ''; + $method = ''; + if (strpos($this->methodname, '..') > 0) { + $delim = '..'; + } else if (strpos($this->methodname, '.') > 0) { + $delim = '.'; + } else { + $delim = ''; + } + + if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && + class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { + // get the class and method name + $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); + $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); + $this->debug("in invoke_method, class=$class method=$method delim=$delim"); + } + + // does method exist? + if ($class == '') { + if (!function_exists($this->methodname)) { + $this->debug("in invoke_method, function '$this->methodname' not found!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } else { + $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; + if (!in_array($method_to_compare, get_class_methods($class))) { + $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } + + // evaluate message, getting back parameters + // verify that request parameters match the method's signature + if(! $this->verify_method($this->methodname,$this->methodparams)){ + // debug + $this->debug('ERROR: request not verified against method signature'); + $this->result = 'fault: request failed validation against method signature'; + // return fault + $this->fault('Client',"Operation '$this->methodname' not defined in service."); + return; + } + + // if there are parameters to pass + $this->debug('in invoke_method, params:'); + $this->appendDebug($this->varDump($this->methodparams)); + $this->debug("in invoke_method, calling '$this->methodname'"); + if (!function_exists('call_user_func_array')) { + if ($class == '') { + $this->debug('in invoke_method, calling function using eval()'); + $funcCall = "\$this->methodreturn = $this->methodname("; + } else { + if ($delim == '..') { + $this->debug('in invoke_method, calling class method using eval()'); + $funcCall = "\$this->methodreturn = ".$class."::".$method."("; + } else { + $this->debug('in invoke_method, calling instance method using eval()'); + // generate unique instance name + $instname = "\$inst_".time(); + $funcCall = $instname." = new ".$class."(); "; + $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; + } + } + if ($this->methodparams) { + foreach ($this->methodparams as $param) { + if (is_array($param)) { + $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); + return; + } + $funcCall .= "\"$param\","; + } + $funcCall = substr($funcCall, 0, -1); + } + $funcCall .= ');'; + $this->debug('in invoke_method, function call: '.$funcCall); + @eval($funcCall); + } else { + if ($class == '') { + $this->debug('in invoke_method, calling function using call_user_func_array()'); + $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() + } elseif ($delim == '..') { + $this->debug('in invoke_method, calling class method using call_user_func_array()'); + $call_arg = array ($class, $method); + } else { + $this->debug('in invoke_method, calling instance method using call_user_func_array()'); + $instance = new $class (); + $call_arg = array(&$instance, $method); + } + $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); + } + $this->debug('in invoke_method, methodreturn:'); + $this->appendDebug($this->varDump($this->methodreturn)); + $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); + } + + /** + * serializes the return value from a PHP function into a full SOAP Envelope + * + * The following fields are set by this function (when successful) + * + * responseSOAP + * + * This sets the fault field on error + * + * @access private + */ + function serialize_return() { + $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); + // if fault + if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) { + $this->debug('got a fault object from method'); + $this->fault = $this->methodreturn; + return; + } elseif ($this->methodreturnisliteralxml) { + $return_val = $this->methodreturn; + // returned value(s) + } else { + $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); + $this->debug('serializing return value'); + if($this->wsdl){ + // weak attempt at supporting multiple output params + if(sizeof($this->opData['output']['parts']) > 1){ + $opParams = $this->methodreturn; + } else { + // TODO: is this really necessary? + $opParams = array($this->methodreturn); + } + $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->fault('Server', 'unable to serialize result'); + return; + } + } else { + if (isset($this->methodreturn)) { + $return_val = $this->serialize_val($this->methodreturn, 'return'); + } else { + $return_val = ''; + $this->debug('in absence of WSDL, assume void return for backward compatibility'); + } + } + } + $this->debug('return value:'); + $this->appendDebug($this->varDump($return_val)); + + $this->debug('serializing response'); + if ($this->wsdl) { + $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); + if ($this->opData['style'] == 'rpc') { + $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); + if ($this->opData['output']['use'] == 'literal') { + $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>"; + } else { + $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; + } + } else { + $this->debug('style is not rpc for serialization: assume document'); + $payload = $return_val; + } + } else { + $this->debug('do not have WSDL for serialization: assume rpc/encoded'); + $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; + } + $this->result = 'successful'; + if($this->wsdl){ + //if($this->debug_flag){ + $this->appendDebug($this->wsdl->getDebug()); + // } + if (isset($opData['output']['encodingStyle'])) { + $encodingStyle = $opData['output']['encodingStyle']; + } else { + $encodingStyle = ''; + } + // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); + } else { + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); + } + $this->debug("Leaving serialize_return"); + } + + /** + * sends an HTTP response + * + * The following fields are set by this function (when successful) + * + * outgoing_headers + * response + * + * @access private + */ + function send_response() { + $this->debug('Enter send_response'); + if ($this->fault) { + $payload = $this->fault->serialize(); + $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; + $this->outgoing_headers[] = "Status: 500 Internal Server Error"; + } else { + $payload = $this->responseSOAP; + // Some combinations of PHP+Web server allow the Status + // to come through as a header. Since OK is the default + // just do nothing. + // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; + // $this->outgoing_headers[] = "Status: 200 OK"; + } + // add debug data if in debug mode + if(isset($this->debug_flag) && $this->debug_flag){ + $payload .= $this->getDebugAsXMLComment(); + } + $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; + // Let the Web server decide about this + //$this->outgoing_headers[] = "Connection: Close\r\n"; + $payload = $this->getHTTPBody($payload); + $type = $this->getHTTPContentType(); + $charset = $this->getHTTPContentTypeCharset(); + $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); + //begin code to compress payload - by John + // NOTE: there is no way to know whether the Web server will also compress + // this data. + if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { + if (strstr($this->headers['accept-encoding'], 'gzip')) { + if (function_exists('gzencode')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content being gzipped -->"; + } + $this->outgoing_headers[] = "Content-Encoding: gzip"; + $payload = gzencode($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content will not be gzipped: no gzencode -->"; + } + } + } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { + // Note: MSIE requires gzdeflate output (no Zlib header and checksum), + // instead of gzcompress output, + // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) + if (function_exists('gzdeflate')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content being deflated -->"; + } + $this->outgoing_headers[] = "Content-Encoding: deflate"; + $payload = gzdeflate($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= "<!-- Content will not be deflated: no gzcompress -->"; + } + } + } + } + //end code + $this->outgoing_headers[] = "Content-Length: ".strlen($payload); + reset($this->outgoing_headers); + foreach($this->outgoing_headers as $hdr){ + header($hdr, false); + } + print $payload; + $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; + } + + /** + * takes the value that was created by parsing the request + * and compares to the method's signature, if available. + * + * @param string $operation The operation to be invoked + * @param array $request The array of parameter values + * @return boolean Whether the operation was found + * @access private + */ + function verify_method($operation,$request){ + if(isset($this->wsdl) && is_object($this->wsdl)){ + if($this->wsdl->getOperationData($operation)){ + return true; + } + } elseif(isset($this->operations[$operation])){ + return true; + } + return false; + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Request not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + // parse response, get soap parser obj + $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8); + // parser debug + $this->debug("parser debug: \n".$parser->getDebug()); + // if fault occurred during message parsing + if($err = $parser->getError()){ + $this->result = 'fault: error in msg parsing: '.$err; + $this->fault('Client',"error in msg parsing:\n".$err); + // else successfully parsed request into soapval object + } else { + // get/set methodname + $this->methodURI = $parser->root_struct_namespace; + $this->methodname = $parser->root_struct_name; + $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); + $this->debug('calling parser->get_response()'); + $this->methodparams = $parser->get_response(); + // get SOAP headers + $this->requestHeaders = $parser->getHeaders(); + // add document for doclit support + $this->document = $parser->document; + } + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /** + * add a method to the dispatch map (this has been replaced by the register method) + * + * @param string $methodname + * @param string $in array of input values + * @param string $out array of output values + * @access public + * @deprecated + */ + function add_to_map($methodname,$in,$out){ + $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); + } + + /** + * register a service function with the server + * + * @param string $name the name of the PHP function, class.method or class..method + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param mixed $namespace the element namespace for the method or false + * @param mixed $soapaction the soapaction for the method or false + * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param mixed $use optional (encoded|literal) or false + * @param string $documentation optional Description to include in WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ + global $HTTP_SERVER_VARS; + + if($this->externalWSDLURL){ + die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); + } + if (! $name) { + die('You must specify a name when you register an operation'); + } + if (!is_array($in)) { + die('You must provide an array for operation inputs'); + } + if (!is_array($out)) { + die('You must provide an array for operation outputs'); + } + if(false == $namespace) { + } + if(false == $soapaction) { + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; + } + if(false == $style) { + $style = "rpc"; + } + if(false == $use) { + $use = "encoded"; + } + if ($use == 'encoded' && $encodingStyle = '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + $this->operations[$name] = array( + 'name' => $name, + 'in' => $in, + 'out' => $out, + 'namespace' => $namespace, + 'soapaction' => $soapaction, + 'style' => $style); + if($this->wsdl){ + $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); + } + return true; + } + + /** + * Specify a fault to be returned to the client. + * This also acts as a flag to the server that a fault has occured. + * + * @param string $faultcode + * @param string $faultstring + * @param string $faultactor + * @param string $faultdetail + * @access public + */ + function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ + if ($faultdetail == '' && $this->debug_flag) { + $faultdetail = $this->getDebug(); + } + $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); + $this->fault->soap_defencoding = $this->soap_defencoding; + } + + /** + * Sets up wsdl object. + * Acts as a flag to enable internal WSDL generation + * + * @param string $serviceName, name of the service + * @param mixed $namespace optional 'tns' service namespace or false + * @param mixed $endpoint optional URL of service endpoint or false + * @param string $style optional (rpc|document) WSDL style (also specified by operation) + * @param string $transport optional SOAP transport + * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false + */ + function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) + { + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SERVER_PORT = $_SERVER['SERVER_PORT']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + $HTTPS = $_SERVER['HTTPS']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + $HTTPS = $HTTP_SERVER_VARS['HTTPS']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + if ($SERVER_PORT == 80) { + $SERVER_PORT = ''; + } else { + $SERVER_PORT = ':' . $SERVER_PORT; + } + if(false == $namespace) { + $namespace = "http://$SERVER_NAME/soap/$serviceName"; + } + + if(false == $endpoint) { + if ($HTTPS == '1' || $HTTPS == 'on') { + $SCHEME = 'https'; + } else { + $SCHEME = 'http'; + } + $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; + } + + if(false == $schemaTargetNamespace) { + $schemaTargetNamespace = $namespace; + } + + $this->wsdl = new wsdl; + $this->wsdl->serviceName = $serviceName; + $this->wsdl->endpoint = $endpoint; + $this->wsdl->namespaces['tns'] = $namespace; + $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; + $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; + if ($schemaTargetNamespace != $namespace) { + $this->wsdl->namespaces['types'] = $schemaTargetNamespace; + } + $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); + $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->bindings[$serviceName.'Binding'] = array( + 'name'=>$serviceName.'Binding', + 'style'=>$style, + 'transport'=>$transport, + 'portType'=>$serviceName.'PortType'); + $this->wsdl->ports[$serviceName.'Port'] = array( + 'binding'=>$serviceName.'Binding', + 'location'=>$endpoint, + 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); + } +} + + + +?><?php + + + +/** +* parses a WSDL file, allows access to it's data, other utility methods +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class wsdl extends nusoap_base { + // URL or filename of the root of this WSDL + var $wsdl; + // define internal arrays of bindings, ports, operations, messages, etc. + var $schemas = array(); + var $currentSchema; + var $message = array(); + var $complexTypes = array(); + var $messages = array(); + var $currentMessage; + var $currentOperation; + var $portTypes = array(); + var $currentPortType; + var $bindings = array(); + var $currentBinding; + var $ports = array(); + var $currentPort; + var $opData = array(); + var $status = ''; + var $documentation = false; + var $endpoint = ''; + // array of wsdl docs to import + var $import = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + // for getting wsdl + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $timeout = 0; + var $response_timeout = 30; + + /** + * constructor + * + * @param string $wsdl WSDL document URL + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ + parent::nusoap_base(); + $this->wsdl = $wsdl; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // parse wsdl file + if ($wsdl != "") { + $this->debug('initial wsdl URL: ' . $wsdl); + $this->parseWSDL($wsdl); + } + // imports + // TODO: handle imports more properly, grabbing them in-line and nesting them + $imported_urls = array(); + $imported = 1; + while ($imported > 0) { + $imported = 0; + // Schema imports + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($xs->imports as $ns2 => $list2) { + for ($ii = 0; $ii < count($list2); $ii++) { + if (! $list2[$ii]['loaded']) { + $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; + $url = $list2[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + } + // WSDL imports + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($this->import as $ns => $list) { + for ($ii = 0; $ii < count($list); $ii++) { + if (! $list[$ii]['loaded']) { + $this->import[$ns][$ii]['loaded'] = true; + $url = $list[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + // add new data to operation data + foreach($this->bindings as $binding => $bindingData) { + if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { + foreach($bindingData['operations'] as $operation => $data) { + $this->debug('post-parse data gathering for ' . $operation); + $this->bindings[$binding]['operations'][$operation]['input'] = + isset($this->bindings[$binding]['operations'][$operation]['input']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['input']; + $this->bindings[$binding]['operations'][$operation]['output'] = + isset($this->bindings[$binding]['operations'][$operation]['output']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['output']; + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; + } + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; + } + if (isset($bindingData['style'])) { + $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; + } + $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; + $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; + $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; + } + } + } + } + + /** + * parses the wsdl document + * + * @param string $wsdl path or URL + * @access private + */ + function parseWSDL($wsdl = '') + { + if ($wsdl == '') { + $this->debug('no wsdl passed to parseWSDL()!!'); + $this->setError('no wsdl passed to parseWSDL()!!'); + return false; + } + + // parse $wsdl for url format + $wsdl_props = parse_url($wsdl); + + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { + $this->debug('getting WSDL http(s) URL ' . $wsdl); + // get wsdl + $tr = new soap_transport_http($wsdl); + $tr->request_method = 'GET'; + $tr->useSOAPAction = false; + if($this->proxyhost && $this->proxyport){ + $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + $tr->setEncoding('gzip, deflate'); + $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); + //$this->debug("WSDL request\n" . $tr->outgoing_payload); + //$this->debug("WSDL response\n" . $tr->incoming_payload); + $this->appendDebug($tr->getDebug()); + // catch errors + if($err = $tr->getError() ){ + $errstr = 'HTTP ERROR: '.$err; + $this->debug($errstr); + $this->setError($errstr); + unset($tr); + return false; + } + unset($tr); + $this->debug("got WSDL URL"); + } else { + // $wsdl is not http(s), so treat it as a file URL or plain file path + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { + $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; + } else { + $path = $wsdl; + } + $this->debug('getting WSDL file ' . $path); + if ($fp = @fopen($path, 'r')) { + $wsdl_string = ''; + while ($data = fread($fp, 32768)) { + $wsdl_string .= $data; + } + fclose($fp); + } else { + $errstr = "Bad path to WSDL file $path"; + $this->debug($errstr); + $this->setError($errstr); + return false; + } + } + $this->debug('Parse WSDL'); + // end new code added + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element', 'end_element'); + xml_set_character_data_handler($this->parser, 'character_data'); + // Parse the XML file. + if (!xml_parse($this->parser, $wsdl_string, true)) { + // Display an error message. + $errstr = sprintf( + 'XML error parsing WSDL from %s on line %d: %s', + $wsdl, + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $wsdl_string); + $this->setError($errstr); + return false; + } + // free the parser + xml_parser_free($this->parser); + $this->debug('Parsing WSDL done'); + // catch wsdl parse errors + if($this->getError()){ + return false; + } + return true; + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) + { + if ($this->status == 'schema') { + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } elseif (ereg('schema$', $name)) { + $this->debug('Parsing WSDL schema'); + // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); + $this->status = 'schema'; + $this->currentSchema = new xmlschema('', '', $this->namespaces); + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } else { + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + // process attributes + if (count($attrs) > 0) { + // register namespace declarations + foreach($attrs as $k => $v) { + if (ereg("^xmlns", $k)) { + if ($ns_prefix = substr(strrchr($k, ':'), 1)) { + $this->namespaces[$ns_prefix] = $v; + } else { + $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; + } + if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v . '-instance'; + } + } + } + // expand each attribute prefix to its namespace + foreach($attrs as $k => $v) { + $k = strpos($k, ':') ? $this->expandQname($k) : $k; + if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { + $v = strpos($v, ':') ? $this->expandQname($v) : $v; + } + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // get element prefix, namespace and name + if (ereg(':', $name)) { + // get ns prefix + $prefix = substr($name, 0, strpos($name, ':')); + // get ns + $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; + // get unqualified name + $name = substr(strstr($name, ':'), 1); + } + // process attributes, expanding any prefixes to namespaces + // find status, register data + switch ($this->status) { + case 'message': + if ($name == 'part') { + if (isset($attrs['type'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; + } + if (isset($attrs['element'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; + } + } + break; + case 'portType': + switch ($name) { + case 'operation': + $this->currentPortOperation = $attrs['name']; + $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); + if (isset($attrs['parameterOrder'])) { + $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; + } + break; + case 'documentation': + $this->documentation = true; + break; + // merge input/output data + default: + $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; + $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; + break; + } + break; + case 'binding': + switch ($name) { + case 'binding': + // get ns prefix + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['prefix'] = $prefix; + } + $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); + break; + case 'header': + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; + break; + case 'operation': + if (isset($attrs['soapAction'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; + } + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; + } + if (isset($attrs['name'])) { + $this->currentOperation = $attrs['name']; + $this->debug("current binding operation: $this->currentOperation"); + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; + } + break; + case 'input': + $this->opStatus = 'input'; + break; + case 'output': + $this->opStatus = 'output'; + break; + case 'body': + if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); + } else { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; + } + break; + } + break; + case 'service': + switch ($name) { + case 'port': + $this->currentPort = $attrs['name']; + $this->debug('current port: ' . $this->currentPort); + $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); + + break; + case 'address': + $this->ports[$this->currentPort]['location'] = $attrs['location']; + $this->ports[$this->currentPort]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; + break; + } + break; + } + // set status + switch ($name) { + case 'import': + if (isset($attrs['location'])) { + $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); + $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); + } else { + $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); + } + break; + //wait for schema + //case 'types': + // $this->status = 'schema'; + // break; + case 'message': + $this->status = 'message'; + $this->messages[$attrs['name']] = array(); + $this->currentMessage = $attrs['name']; + break; + case 'portType': + $this->status = 'portType'; + $this->portTypes[$attrs['name']] = array(); + $this->currentPortType = $attrs['name']; + break; + case "binding": + if (isset($attrs['name'])) { + // get binding name + if (strpos($attrs['name'], ':')) { + $this->currentBinding = $this->getLocalPart($attrs['name']); + } else { + $this->currentBinding = $attrs['name']; + } + $this->status = 'binding'; + $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); + $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); + } + break; + case 'service': + $this->serviceName = $attrs['name']; + $this->status = 'service'; + $this->debug('current service: ' . $this->serviceName); + break; + case 'definitions': + foreach ($attrs as $name => $value) { + $this->wsdl_info[$name] = $value; + } + break; + } + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name){ + // unset schema status + if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { + $this->status = ""; + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; + $this->debug('Parsing WSDL schema done'); + } + if ($this->status == 'schema') { + $this->currentSchema->schemaEndElement($parser, $name); + } else { + // bring depth down a notch + $this->depth--; + } + // end documentation + if ($this->documentation) { + //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. + //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; + $this->documentation = false; + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data) + { + $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; + if (isset($this->message[$pos]['cdata'])) { + $this->message[$pos]['cdata'] .= $data; + } + if ($this->documentation) { + $this->documentation .= $data; + } + } + + function getBindingData($binding) + { + if (is_array($this->bindings[$binding])) { + return $this->bindings[$binding]; + } + } + + /** + * returns an assoc array of operation names => operation data + * + * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) + * @return array + * @access public + */ + function getOperations($bindingType = 'soap') + { + $ops = array(); + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + //$this->debug("getOperations for port $port"); + //$this->debug("port data: " . $this->varDump($portData)); + //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); + // merge bindings + if (isset($this->bindings[ $portData['binding'] ]['operations'])) { + $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); + } + } + } + return $ops; + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $operation , name of operation + * @param string $bindingType , type of binding eg: soap + * @return array + * @access public + */ + function getOperationData($operation, $bindingType = 'soap') + { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // get binding + //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { + // note that we could/should also check the namespace here + if ($operation == $bOperation) { + $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; + return $opData; + } + } + } + } + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $soapAction soapAction for operation + * @param string $bindingType type of binding eg: soap + * @return array + * @access public + */ + function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // loop through operations for the binding + foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + if ($opData['soapAction'] == $soapAction) { + return $opData; + } + } + } + } + } + + /** + * returns an array of information about a given type + * returns false if no type exists by the given name + * + * typeDef = array( + * 'elements' => array(), // refs to elements array + * 'restrictionBase' => '', + * 'phpType' => '', + * 'order' => '(sequence|all)', + * 'attrs' => array() // refs to attributes array + * ) + * + * @param $type string the type + * @param $ns string namespace (not prefix) of the type + * @return mixed + * @access public + * @see xmlschema + */ + function getTypeDef($type, $ns) { + $this->debug("in getTypeDef: type=$type, ns=$ns"); + if ((! $ns) && isset($this->namespaces['tns'])) { + $ns = $this->namespaces['tns']; + $this->debug("in getTypeDef: type namespace forced to $ns"); + } + if (isset($this->schemas[$ns])) { + $this->debug("in getTypeDef: have schema for namespace $ns"); + for ($i = 0; $i < count($this->schemas[$ns]); $i++) { + $xs = &$this->schemas[$ns][$i]; + $t = $xs->getTypeDef($type); + $this->appendDebug($xs->getDebug()); + $xs->clearDebug(); + if ($t) { + if (!isset($t['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); + $ns = substr($t['type'], 0, strrpos($t['type'], ':')); + $etype = $this->getTypeDef($uqType, $ns); + if ($etype) { + $this->debug("found type for [element] $type:"); + $this->debug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $t['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $t['elements'] = $etype['elements']; + } + if (isset($etype['attrs'])) { + $t['attrs'] = $etype['attrs']; + } + } + } + return $t; + } + } + } else { + $this->debug("in getTypeDef: do not have schema for namespace $ns"); + } + return false; + } + + /** + * prints html description of services + * + * @access private + */ + function webDescription(){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $PHP_SELF = $_SERVER['PHP_SELF']; + } elseif (isset($HTTP_SERVER_VARS)) { + $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + + $b = ' + <html><head><title>NuSOAP: '.$this->serviceName.'</title> + <style type="text/css"> + body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } + p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } + pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} + ul { margin-top: 10px; margin-left: 20px; } + li { list-style-type: none; margin-top: 10px; color: #000000; } + .content{ + margin-left: 0px; padding-bottom: 2em; } + .nav { + padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; + margin-top: 10px; margin-left: 0px; color: #000000; + background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } + .title { + font-family: arial; font-size: 26px; color: #ffffff; + background-color: #999999; width: 105%; margin-left: 0px; + padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} + .hidden { + position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; + font-family: arial; overflow: hidden; width: 600; + padding: 20px; font-size: 10px; background-color: #999999; + layer-background-color:#FFFFFF; } + a,a:active { color: charcoal; font-weight: bold; } + a:visited { color: #666666; font-weight: bold; } + a:hover { color: cc3300; font-weight: bold; } + </style> + <script language="JavaScript" type="text/javascript"> + <!-- + // POP-UP CAPTIONS... + function lib_bwcheck(){ //Browsercheck (needed) + this.ver=navigator.appVersion + this.agent=navigator.userAgent + this.dom=document.getElementById?1:0 + this.opera5=this.agent.indexOf("Opera 5")>-1 + this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; + this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; + this.ie4=(document.all && !this.dom && !this.opera5)?1:0; + this.ie=this.ie4||this.ie5||this.ie6 + this.mac=this.agent.indexOf("Mac")>-1 + this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; + this.ns4=(document.layers && !this.dom)?1:0; + this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) + return this + } + var bw = new lib_bwcheck() + //Makes crossbrowser object. + function makeObj(obj){ + this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; + if(!this.evnt) return false + this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; + this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; + this.writeIt=b_writeIt; + return this + } + // A unit of measure that will be added when setting the position of a layer. + //var px = bw.ns4||window.opera?"":"px"; + function b_writeIt(text){ + if (bw.ns4){this.wref.write(text);this.wref.close()} + else this.wref.innerHTML = text + } + //Shows the messages + var oDesc; + function popup(divid){ + if(oDesc = new makeObj(divid)){ + oDesc.css.visibility = "visible" + } + } + function popout(){ // Hides message + if(oDesc) oDesc.css.visibility = "hidden" + } + //--> + </script> + </head> + <body> + <div class=content> + <br><br> + <div class=title>'.$this->serviceName.'</div> + <div class=nav> + <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service. + Click on an operation name to view it's details.</p> + <ul>'; + foreach($this->getOperations() as $op => $data){ + $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>"; + // create hidden div + $b .= "<div id='$op' class='hidden'> + <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>"; + foreach($data as $donnie => $marie){ // loop through opdata + if($donnie == 'input' || $donnie == 'output'){ // show input/output data + $b .= "<font color='white'>".ucfirst($donnie).':</font><br>'; + foreach($marie as $captain => $tenille){ // loop through data + if($captain == 'parts'){ // loop thru parts + $b .= " $captain:<br>"; + //if(is_array($tenille)){ + foreach($tenille as $joanie => $chachi){ + $b .= " $joanie: $chachi<br>"; + } + //} + } else { + $b .= " $captain: $tenille<br>"; + } + } + } else { + $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>"; + } + } + $b .= '</div>'; + } + $b .= ' + <ul> + </div> + </div></body></html>'; + return $b; + } + + /** + * serialize the parsed wsdl + * + * @param mixed $debug whether to put debug=1 in endpoint URL + * @return string serialization of WSDL + * @access public + */ + function serialize($debug = 0) + { + $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'; + $xml .= "\n<definitions"; + foreach($this->namespaces as $k => $v) { + $xml .= " xmlns:$k=\"$v\""; + } + // 10.9.02 - add poulter fix for wsdl and tns declarations + if (isset($this->namespaces['wsdl'])) { + $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; + } + if (isset($this->namespaces['tns'])) { + $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; + } + $xml .= '>'; + // imports + if (sizeof($this->import) > 0) { + foreach($this->import as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />'; + } else { + $xml .= '<import namespace="' . $ns . '" />'; + } + } + } + } + // types + if (count($this->schemas)>=1) { + $xml .= "\n<types>"; + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $xml .= $xs->serializeSchema(); + } + } + $xml .= '</types>'; + } + // messages + if (count($this->messages) >= 1) { + foreach($this->messages as $msgName => $msgParts) { + $xml .= "\n<message name=\"" . $msgName . '">'; + if(is_array($msgParts)){ + foreach($msgParts as $partName => $partType) { + // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>'; + if (strpos($partType, ':')) { + $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); + } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { + // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>'; + $typePrefix = 'xsd'; + } else { + foreach($this->typemap as $ns => $types) { + if (isset($types[$partType])) { + $typePrefix = $this->getPrefixFromNamespace($ns); + } + } + if (!isset($typePrefix)) { + die("$partType has no namespace!"); + } + } + $ns = $this->getNamespaceFromPrefix($typePrefix); + $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); + if ($typeDef['typeClass'] == 'element') { + $elementortype = 'element'; + } else { + $elementortype = 'type'; + } + $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />'; + } + } + $xml .= '</message>'; + } + } + // bindings & porttypes + if (count($this->bindings) >= 1) { + $binding_xml = ''; + $portType_xml = ''; + foreach($this->bindings as $bindingName => $attrs) { + $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">'; + $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>'; + $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">'; + foreach($attrs['operations'] as $opName => $opParts) { + $binding_xml .= '<operation name="' . $opName . '">'; + $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>'; + if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>'; + if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>'; + $binding_xml .= '</operation>'; + $portType_xml .= '<operation name="' . $opParts['name'] . '"'; + if (isset($opParts['parameterOrder'])) { + $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"'; + } + $portType_xml .= '>'; + if(isset($opParts['documentation']) && $opParts['documentation'] != '') { + $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>'; + } + $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>'; + $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>'; + $portType_xml .= '</operation>'; + } + $portType_xml .= '</portType>'; + $binding_xml .= '</binding>'; + } + $xml .= $portType_xml . $binding_xml; + } + // services + $xml .= "\n<service name=\"" . $this->serviceName . '">'; + if (count($this->ports) >= 1) { + foreach($this->ports as $pName => $attrs) { + $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">'; + $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>'; + $xml .= '</port>'; + } + } + $xml .= '</service>'; + return $xml . "\n</definitions>"; + } + + /** + * serialize PHP values according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $operation operation name + * @param string $direction (input|output) + * @param mixed $parameters parameter value(s) + * @return mixed parameters serialized as XML or false on error (e.g. operation not found) + * @access public + */ + function serializeRPCParameters($operation, $direction, $parameters) + { + $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeRPCParameters returning: $xml"); + return $xml; + } + + /** + * serialize a PHP value according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $ type name + * @param mixed $ param value + * @return mixed new param or false if initial value didn't validate + * @access public + * @deprecated + */ + function serializeParameters($operation, $direction, $parameters) + { + $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug("use=$use"); + $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . $parametersArrayType . ' parameters'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeParameters returning: $xml"); + return $xml; + } + + /** + * serializes a PHP value according a given type definition + * + * @param string $name name of value (part or element) + * @param string $type XML schema type of value (type or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @param boolean $unqualified a kludge for what should be XML namespace form handling + * @return string value serialized as an XML string + * @access private + */ + function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) + { + $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); + $this->appendDebug("value=" . $this->varDump($value)); + if($use == 'encoded' && $encodingStyle) { + $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; + } + + // if a soapval has been supplied, let its type override the WSDL + if (is_object($value) && get_class($value) == 'soapval') { + if ($value->type_ns) { + $type = $value->type_ns . ':' . $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } elseif ($value->type) { + $type = $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } else { + $forceType = false; + $this->debug("in serializeType: soapval does not override type"); + } + $attrs = $value->attributes; + $value = $value->value; + $this->debug("in serializeType: soapval overrides value to $value"); + if ($attrs) { + if (!is_array($value)) { + $value['!'] = $value; + } + foreach ($attrs as $n => $v) { + $value['!' . $n] = $v; + } + $this->debug("in serializeType: soapval provides attributes"); + } + } else { + $forceType = false; + } + + $xml = ''; + if (strpos($type, ':')) { + $uqType = substr($type, strrpos($type, ':') + 1); + $ns = substr($type, 0, strrpos($type, ':')); + $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); + } + + if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ + $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); + if ($unqualified && $use == 'literal') { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + // TODO: depends on nillable, which should be checked before calling this method + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if ($uqType == 'boolean') { + if ((is_string($value) && $value == 'false') || (! $value)) { + $value = 'false'; + } else { + $value = 'true'; + } + } + if ($uqType == 'string' && gettype($value) == 'string') { + $value = $this->expandEntities($value); + } + if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { + $value = sprintf("%.0lf", $value); + } + // it's a scalar + // TODO: what about null/nil values? + // check type isn't a custom type extending xmlschema namespace + if (!$this->getTypeDef($uqType, $ns)) { + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; + } else { + $xml = "<$name$elementNS>$value</$name>"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); + } else if ($ns == 'http://xml.apache.org/xml-soap') { + $this->debug('in serializeType: appears to be Apache SOAP type'); + if ($uqType == 'Map') { + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + if (! $tt_prefix) { + $this->debug('in serializeType: Add namespace for Apache SOAP type'); + $tt_prefix = 'ns' . rand(1000, 9999); + $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; + // force this to be added to usedNamespaces + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + } + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing map element: key $k, value $v"); + $contents .= '<item>'; + $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); + $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); + $contents .= '</item>'; + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>"; + } else { + $xml = "<$name>$contents</$name>"; + } + } else { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('in serializeType: Apache SOAP type, but only support Map'); + } + } else { + // TODO: should the type be compared to types in XSD, and the namespace + // set to XSD if the type matches? + $this->debug("in serializeType: No namespace for type $type"); + $ns = ''; + $uqType = $type; + } + if(!$typeDef = $this->getTypeDef($uqType, $ns)){ + $this->setError("$type ($uqType) is not a supported type."); + $this->debug("in serializeType: $type ($uqType) is not a supported type."); + return false; + } else { + $this->debug("in serializeType: found typeDef"); + $this->appendDebug('typeDef=' . $this->varDump($typeDef)); + } + $phpType = $typeDef['phpType']; + $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); + // if php type == struct, map value to the <all> element names + if ($phpType == 'struct') { + if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { + $elementName = $uqType; + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = " xmlns=\"\""; + } + } else { + $elementName = $name; + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$elementName$elementNS/>"; + } else { + $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (is_object($value)) { + $value = get_object_vars($value); + } + if (is_array($value)) { + $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + if ($use == 'literal') { + if ($forceType) { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; + } else { + $xml = "<$elementName$elementNS$elementAttrs>"; + } + } else { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; + } + + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + $xml .= "</$elementName>"; + } else { + $this->debug("in serializeType: phpType is struct, but value is not an array"); + $this->setError("phpType is struct, but value is not an array: see debug output for details"); + $xml = ''; + } + } elseif ($phpType == 'array') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ":Array\" " . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ':arrayType="' . + $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . + ':' . + $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (isset($typeDef['multidimensional'])) { + $nv = array(); + foreach($value as $v) { + $cols = ',' . sizeof($v); + $nv = array_merge($nv, $v); + } + $value = $nv; + } else { + $cols = ''; + } + if (is_array($value) && sizeof($value) >= 1) { + $rows = sizeof($value); + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); + //if (strpos($typeDef['arrayType'], ':') ) { + if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { + $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); + } else { + $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); + } + } + } else { + $rows = 0; + $contents = null; + } + // TODO: for now, an empty value will be serialized as a zero element + // array. Revisit this when coding the handling of null/nil values. + if ($use == 'literal') { + $xml = "<$name$elementNS>" + .$contents + ."</$name>"; + } else { + $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') + .':arrayType="' + .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) + .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" + .$contents + ."</$name>"; + } + } elseif ($phpType == 'scalar') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; + } else { + $xml = "<$name$elementNS>$value</$name>"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; + } + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + + /** + * serializes the attributes for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { + $xml = ''; + if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { + $this->debug("serialize attributes for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + foreach ($typeDef['attrs'] as $aName => $attrs) { + if (isset($xvalue['!' . $aName])) { + $xname = '!' . $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($xvalue[$aName])) { + $xname = $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($attrs['default'])) { + $xname = '!' . $aName; + $xvalue[$xname] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); + } else { + $xname = ''; + $this->debug("no value provided for attribute $aName"); + } + if ($xname) { + $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; + } + } + } else { + $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize attributes for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * serializes the elements for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { + $xml = ''; + if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { + $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + // toggle whether all elements are present - ideally should validate against schema + if (count($typeDef['elements']) != count($xvalue)){ + $optionals = true; + } + foreach ($typeDef['elements'] as $eName => $attrs) { + if (!isset($xvalue[$eName])) { + if (isset($attrs['default'])) { + $xvalue[$eName] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); + } + } + // if user took advantage of a minOccurs=0, then only serialize named parameters + if (isset($optionals) + && (!isset($xvalue[$eName])) + && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') + ){ + if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { + $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); + } + // do nothing + $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); + } else { + // get value + if (isset($xvalue[$eName])) { + $v = $xvalue[$eName]; + } else { + $v = null; + } + if (isset($attrs['form'])) { + $unqualified = ($attrs['form'] == 'unqualified'); + } else { + $unqualified = false; + } + if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { + $vv = $v; + foreach ($vv as $k => $v) { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } else { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } + } + } else { + $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize elements for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * adds an XML Schema complex type to the WSDL types + * + * @param string name + * @param string typeClass (complexType|simpleType|attribute) + * @param string phpType: currently supported are array and struct (php assoc array) + * @param string compositor (all|sequence|choice) + * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param array elements = array ( name => array(name=>'',type=>'') ) + * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) + * @param string arrayType: namespace:name (xsd:string) + * @see xmlschema + * @access public + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { + if (count($elements) > 0) { + foreach($elements as $n => $e){ + // expand each element + foreach ($e as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $ee[$k] = $v; + } + $eElements[$n] = $ee; + } + $elements = $eElements; + } + + if (count($attrs) > 0) { + foreach($attrs as $n => $a){ + // expand each attribute + foreach ($a as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $aa[$k] = $v; + } + $eAttrs[$n] = $aa; + } + $attrs = $eAttrs; + } + + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); + } + + /** + * adds an XML Schema simple type to the WSDL types + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @see xmlschema + * @access public + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); + } + + /** + * adds an element to the WSDL types + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addElement($attrs); + } + + /** + * register an operation with the server + * + * @param string $name operation (method) name + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param string $namespace optional The namespace for the operation + * @param string $soapaction optional The soapaction for the operation + * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) + * @param string $documentation optional The description to include in the WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ + if ($use == 'encoded' && $encodingStyle == '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + if ($style == 'document') { + $elements = array(); + foreach ($in as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); + $in = array('parameters' => 'tns:' . $name); + + $elements = array(); + foreach ($out as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); + $out = array('parameters' => 'tns:' . $name . 'Response'); + } + + // get binding + $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = + array( + 'name' => $name, + 'binding' => $this->serviceName . 'Binding', + 'endpoint' => $this->endpoint, + 'soapAction' => $soapaction, + 'style' => $style, + 'input' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Request', + 'parts' => $in), + 'output' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Response', + 'parts' => $out), + 'namespace' => $namespace, + 'transport' => 'http://schemas.xmlsoap.org/soap/http', + 'documentation' => $documentation); + // add portTypes + // add messages + if($in) + { + foreach($in as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Request'][$pName] = $pType; + } + } else { + $this->messages[$name.'Request']= '0'; + } + if($out) + { + foreach($out as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Response'][$pName] = $pType; + } + } else { + $this->messages[$name.'Response']= '0'; + } + return true; + } +} +?><?php + + + +/** +* +* soap_parser class parses SOAP XML messages into native PHP values +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soap_parser extends nusoap_base { + + var $xml = ''; + var $xml_encoding = ''; + var $method = ''; + var $root_struct = ''; + var $root_struct_name = ''; + var $root_struct_namespace = ''; + var $root_header = ''; + var $document = ''; // incoming SOAP body (text) + // determines where in the message we are (envelope,header,body,method) + var $status = ''; + var $position = 0; + var $depth = 0; + var $default_namespace = ''; + var $namespaces = array(); + var $message = array(); + var $parent = ''; + var $fault = false; + var $fault_code = ''; + var $fault_str = ''; + var $fault_detail = ''; + var $depth_array = array(); + var $debug_flag = true; + var $soapresponse = NULL; + var $responseHeaders = ''; // incoming SOAP headers (text) + var $body_position = 0; + // for multiref parsing: + // array of id => pos + var $ids = array(); + // array of id => hrefs => pos + var $multirefs = array(); + // toggle for auto-decoding element content + var $decode_utf8 = true; + + /** + * constructor that actually does the parsing + * + * @param string $xml SOAP message + * @param string $encoding character encoding scheme of message + * @param string $method method for which XML is parsed (unused?) + * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 + * @access public + */ + function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ + parent::nusoap_base(); + $this->xml = $xml; + $this->xml_encoding = $encoding; + $this->method = $method; + $this->decode_utf8 = $decode_utf8; + + // Check whether content has been read. + if(!empty($xml)){ + // Check XML encoding + $pos_xml = strpos($xml, '<?xml'); + if ($pos_xml !== FALSE) { + $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1); + if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { + $xml_encoding = $res[1]; + if (strtoupper($xml_encoding) != $encoding) { + $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; + $this->debug($err); + if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { + $this->setError($err); + return; + } + // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed + } else { + $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); + } + } else { + $this->debug('No encoding specified in XML declaration'); + } + } else { + $this->debug('No XML declaration'); + } + $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); + // Create an XML parser - why not xml_parser_create_ns? + $this->parser = xml_parser_create($this->xml_encoding); + // Set the options for parsing the XML data. + //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element','end_element'); + xml_set_character_data_handler($this->parser,'character_data'); + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $err = sprintf('XML error parsing SOAP payload on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser))); + $this->debug($err); + $this->debug("XML payload:\n" . $xml); + $this->setError($err); + } else { + $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); + // get final value + $this->soapresponse = $this->message[$this->root_struct]['result']; + // get header value: no, because this is documented as XML string +// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ +// $this->responseHeaders = $this->message[$this->root_header]['result']; +// } + // resolve hrefs/ids + if(sizeof($this->multirefs) > 0){ + foreach($this->multirefs as $id => $hrefs){ + $this->debug('resolving multirefs for id: '.$id); + $idVal = $this->buildVal($this->ids[$id]); + if (is_array($idVal) && isset($idVal['!id'])) { + unset($idVal['!id']); + } + foreach($hrefs as $refPos => $ref){ + $this->debug('resolving href at pos '.$refPos); + $this->multirefs[$id][$refPos] = $idVal; + } + } + } + } + xml_parser_free($this->parser); + } else { + $this->debug('xml was empty, didn\'t parse!'); + $this->setError('xml was empty, didn\'t parse!'); + } + } + + /** + * start-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @param array $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) { + // position in a total number of elements, starting from 0 + // update class level pos + $pos = $this->position++; + // and set mine + $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); + // depth = how many levels removed from root? + // set mine as current global depth and increment global depth value + $this->message[$pos]['depth'] = $this->depth++; + + // else add self as child to whoever the current parent is + if($pos != 0){ + $this->message[$this->parent]['children'] .= '|'.$pos; + } + // set my parent + $this->message[$pos]['parent'] = $this->parent; + // set self as current parent + $this->parent = $pos; + // set self as current value for this depth + $this->depth_array[$this->depth] = $pos; + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + // set status + if($name == 'Envelope'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->root_header = $pos; + $this->status = 'header'; + } elseif($name == 'Body'){ + $this->status = 'body'; + $this->body_position = $pos; + // set method + } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->message[$pos]['type'] = 'struct'; + $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); + } + // set my status + $this->message[$pos]['status'] = $this->status; + // set name + $this->message[$pos]['name'] = htmlspecialchars($name); + // set attrs + $this->message[$pos]['attrs'] = $attrs; + + // loop through atts, logging ns and type declarations + $attstr = ''; + foreach($attrs as $key => $value){ + $key_prefix = $this->getPrefix($key); + $key_localpart = $this->getLocalPart($key); + // if ns declarations, add to class level array of valid namespaces + if($key_prefix == 'xmlns'){ + if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ + $this->XMLSchemaVersion = $value; + $this->namespaces['xsd'] = $this->XMLSchemaVersion; + $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; + } + $this->namespaces[$key_localpart] = $value; + // set method namespace + if($name == $this->root_struct_name){ + $this->methodNamespace = $value; + } + // if it's a type declaration, set type + } elseif($key_localpart == 'type'){ + $value_prefix = $this->getPrefix($value); + $value_localpart = $this->getLocalPart($value); + $this->message[$pos]['type'] = $value_localpart; + $this->message[$pos]['typePrefix'] = $value_prefix; + if(isset($this->namespaces[$value_prefix])){ + $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; + } else if(isset($attrs['xmlns:'.$value_prefix])) { + $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; + } + // should do something here with the namespace of specified type? + } elseif($key_localpart == 'arrayType'){ + $this->message[$pos]['type'] = 'array'; + /* do arrayType ereg here + [1] arrayTypeValue ::= atype asize + [2] atype ::= QName rank* + [3] rank ::= '[' (',')* ']' + [4] asize ::= '[' length~ ']' + [5] length ::= nextDimension* Digit+ + [6] nextDimension ::= Digit+ ',' + */ + $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; + if(ereg($expr,$value,$regs)){ + $this->message[$pos]['typePrefix'] = $regs[1]; + $this->message[$pos]['arrayTypePrefix'] = $regs[1]; + if (isset($this->namespaces[$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; + } else if (isset($attrs['xmlns:'.$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; + } + $this->message[$pos]['arrayType'] = $regs[2]; + $this->message[$pos]['arraySize'] = $regs[3]; + $this->message[$pos]['arrayCols'] = $regs[4]; + } + // specifies nil value (or not) + } elseif ($key_localpart == 'nil'){ + $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); + // some other attribute + } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { + $this->message[$pos]['xattrs']['!' . $key] = $value; + } + + if ($key == 'xmlns') { + $this->default_namespace = $value; + } + // log id + if($key == 'id'){ + $this->ids[$value] = $pos; + } + // root + if($key_localpart == 'root' && $value == 1){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->debug("found root struct $this->root_struct_name, pos $pos"); + } + // for doclit + $attstr .= " $key=\"$value\""; + } + // get namespace - must be done after namespace atts are processed + if(isset($prefix)){ + $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; + $this->default_namespace = $this->namespaces[$prefix]; + } else { + $this->message[$pos]['namespace'] = $this->default_namespace; + } + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } elseif($this->root_struct_name != ''){ + $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } + + /** + * end-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name) { + // position of current element is equal to the last value left in depth_array for my depth + $pos = $this->depth_array[$this->depth--]; + + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + + // build to native type + if(isset($this->body_position) && $pos > $this->body_position){ + // deal w/ multirefs + if(isset($this->message[$pos]['attrs']['href'])){ + // get id + $id = substr($this->message[$pos]['attrs']['href'],1); + // add placeholder to href array + $this->multirefs[$id][$pos] = 'placeholder'; + // add set a reference to it as the result value + $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; + // build complexType values + } elseif($this->message[$pos]['children'] != ''){ + // if result has already been generated (struct/array) + if(!isset($this->message[$pos]['result'])){ + $this->message[$pos]['result'] = $this->buildVal($pos); + } + // build complexType values of attributes and possibly simpleContent + } elseif (isset($this->message[$pos]['xattrs'])) { + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + if (isset($this->message[$pos]['type'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; + } + } + } + $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; + // set value of simpleType (or nil complexType) + } else { + //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['type'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['result'] = $this->message[$pos]['cdata']; + } + } + + /* add value to parent's result, if parent is struct/array + $parent = $this->message[$pos]['parent']; + if($this->message[$parent]['type'] != 'map'){ + if(strtolower($this->message[$parent]['type']) == 'array'){ + $this->message[$parent]['result'][] = $this->message[$pos]['result']; + } else { + $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; + } + } + */ + } + } + + // for doclit + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; + } + } elseif($pos >= $this->root_struct){ + $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; + } + // switch status + if($pos == $this->root_struct){ + $this->status = 'body'; + $this->root_struct_namespace = $this->message[$pos]['namespace']; + } elseif($name == 'Body'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->status = 'envelope'; + } elseif($name == 'Envelope'){ + // + } + // set parent back to my parent + $this->parent = $this->message[$pos]['parent']; + } + + /** + * element content handler + * + * @param resource $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data){ + $pos = $this->depth_array[$this->depth]; + if ($this->xml_encoding=='UTF-8'){ + // TODO: add an option to disable this for folks who want + // raw UTF-8 that, e.g., might not map to iso-8859-1 + // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); + if($this->decode_utf8){ + $data = utf8_decode($data); + } + } + $this->message[$pos]['cdata'] .= $data; + // for doclit + if($this->status == 'header'){ + $this->responseHeaders .= $data; + } else { + $this->document .= $data; + } + } + + /** + * get the parsed message + * + * @return mixed + * @access public + */ + function get_response(){ + return $this->soapresponse; + } + + /** + * get the parsed headers + * + * @return string XML or empty if no headers + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * decodes simple types into PHP variables + * + * @param string $value value to decode + * @param string $type XML type to decode + * @param string $typens XML type namespace to decode + * @return mixed PHP value + * @access private + */ + function decodeSimple($value, $type, $typens) { + // TODO: use the namespace! + if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { + return (string) $value; + } + if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { + return (int) $value; + } + if ($type == 'float' || $type == 'double' || $type == 'decimal') { + return (double) $value; + } + if ($type == 'boolean') { + if (strtolower($value) == 'false' || strtolower($value) == 'f') { + return false; + } + return (boolean) $value; + } + if ($type == 'base64' || $type == 'base64Binary') { + $this->debug('Decode base64 value'); + return base64_decode($value); + } + // obscure numeric types + if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' + || $type == 'nonNegativeInteger' || $type == 'positiveInteger' + || $type == 'unsignedInt' + || $type == 'unsignedShort' || $type == 'unsignedByte') { + return (int) $value; + } + // bogus: parser treats array with no elements as a simple type + if ($type == 'array') { + return array(); + } + // everything else + return (string) $value; + } + + /** + * builds response structures for compound values (arrays/structs) + * and scalars + * + * @param integer $pos position in node tree + * @return mixed PHP value + * @access private + */ + function buildVal($pos){ + if(!isset($this->message[$pos]['type'])){ + $this->message[$pos]['type'] = ''; + } + $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); + // if there are children... + if($this->message[$pos]['children'] != ''){ + $this->debug('in buildVal, there are children'); + $children = explode('|',$this->message[$pos]['children']); + array_shift($children); // knock off empty + // md array + if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ + $r=0; // rowcount + $c=0; // colcount + foreach($children as $child_pos){ + $this->debug("in buildVal, got an MD array element: $r, $c"); + $params[$r][] = $this->message[$child_pos]['result']; + $c++; + if($c == $this->message[$pos]['arrayCols']){ + $c = 0; + $r++; + } + } + // array + } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ + $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $params[] = &$this->message[$child_pos]['result']; + } + // apache Map type: java hashtable + } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ + $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $kv = explode("|",$this->message[$child_pos]['children']); + $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; + } + // generic compound type + //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { + } else { + // Apache Vector type: treat as an array + $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); + if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { + $notstruct = 1; + } else { + $notstruct = 0; + } + // + foreach($children as $child_pos){ + if($notstruct){ + $params[] = &$this->message[$child_pos]['result']; + } else { + if (isset($params[$this->message[$child_pos]['name']])) { + // de-serialize repeated element name into an array + if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { + $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); + } + $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; + } else { + $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; + } + } + } + } + if (isset($this->message[$pos]['xattrs'])) { + $this->debug('in buildVal, handling attributes'); + foreach ($this->message[$pos]['xattrs'] as $n => $v) { + $params[$n] = $v; + } + } + // handle simpleContent + if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + $this->debug('in buildVal, handling simpleContent'); + if (isset($this->message[$pos]['type'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $params['!'] = $this->message[$pos]['cdata']; + } + } + } + return is_array($params) ? $params : array(); + } else { + $this->debug('in buildVal, no children, building scalar'); + $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; + if (isset($this->message[$pos]['type'])) { + return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } + return $this->message[$pos]['cdata']; + } + } +} + + + +?><?php + + + +/** +* +* soapclient higher level class for easy usage. +* +* usage: +* +* // instantiate client with server info +* $soapclient = new soapclient( string path [ ,boolean wsdl] ); +* +* // call method, get results +* echo $soapclient->call( string methodname [ ,array parameters] ); +* +* // bye bye client +* unset($soapclient); +* +* @author Dietrich Ayala <dietrich@ganx4.com> +* @version $Id$ +* @access public +*/ +class soapclient extends nusoap_base { + + var $username = ''; + var $password = ''; + var $authtype = ''; + var $certRequest = array(); + var $requestHeaders = false; // SOAP headers in request (text) + var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) + var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) + var $endpoint; + var $forceEndpoint = ''; // overrides WSDL endpoint + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $xml_encoding = ''; // character set encoding of incoming (response) messages + var $http_encoding = false; + var $timeout = 0; // HTTP connection timeout + var $response_timeout = 30; // HTTP response timeout + var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error + var $persistentConnection = false; + var $defaultRpcParams = false; // This is no longer used + var $request = ''; // HTTP request + var $response = ''; // HTTP response + var $responseData = ''; // SOAP payload of response + var $cookies = array(); // Cookies from response or for request + var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() + var $operations = array(); // WSDL operations, empty for WSDL initialization error + + /* + * fault related variables + */ + /** + * @var fault + * @access public + */ + var $fault; + /** + * @var faultcode + * @access public + */ + var $faultcode; + /** + * @var faultstring + * @access public + */ + var $faultstring; + /** + * @var faultdetail + * @access public + */ + var $faultdetail; + + /** + * constructor + * + * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) + * @param bool $wsdl optional, set to true if using WSDL + * @param int $portName optional portName in WSDL document + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ + parent::nusoap_base(); + $this->endpoint = $endpoint; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // make values + if($wsdl){ + if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { + $this->wsdl = $endpoint; + $this->endpoint = $this->wsdl->wsdl; + $this->wsdlFile = $this->endpoint; + $this->debug('existing wsdl instance created from ' . $this->endpoint); + } else { + $this->wsdlFile = $this->endpoint; + + // instantiate wsdl object and parse wsdl file + $this->debug('instantiating wsdl class with doc: '.$endpoint); + $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + // catch errors + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + } elseif($this->operations = $this->wsdl->getOperations()){ + $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); + $this->endpointType = 'wsdl'; + } else { + $this->debug( 'getOperations returned false'); + $this->setError('no operations defined in the WSDL document!'); + } + } else { + $this->debug("instantiate SOAP with endpoint at $endpoint"); + $this->endpointType = 'soap'; + } + } + + /** + * calls method, returns PHP native type + * + * @param string $method SOAP server URL or path + * @param mixed $params An array, associative or simple, of the parameters + * for the method call, or a string that is the XML + * for the call. For rpc style, this call will + * wrap the XML in a tag named after the method, as + * well as the SOAP Envelope and Body. For document + * style, this will only wrap with the Envelope and Body. + * IMPORTANT: when using an array with document style, + * in which case there + * is really one parameter, the root of the fragment + * used in the call, which encloses what programmers + * normally think of parameters. A parameter array + * *must* include the wrapper. + * @param string $namespace optional method namespace (WSDL can override) + * @param string $soapAction optional SOAPAction value (WSDL can override) + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param boolean $rpcParams optional (no longer used) + * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) + * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) + * @return mixed response from SOAP call + * @access public + */ + function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ + $this->operation = $operation; + $this->fault = false; + $this->setError(''); + $this->request = ''; + $this->response = ''; + $this->responseData = ''; + $this->faultstring = ''; + $this->faultcode = ''; + $this->opData = array(); + + $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); + $this->appendDebug('params=' . $this->varDump($params)); + $this->appendDebug('headers=' . $this->varDump($headers)); + if ($headers) { + $this->requestHeaders = $headers; + } + // serialize parameters + if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ + // use WSDL for operation + $this->opData = $opData; + $this->debug("found operation"); + $this->appendDebug('opData=' . $this->varDump($opData)); + if (isset($opData['soapAction'])) { + $soapAction = $opData['soapAction']; + } + if (! $this->forceEndpoint) { + $this->endpoint = $opData['endpoint']; + } else { + $this->endpoint = $this->forceEndpoint; + } + $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; + $style = $opData['style']; + $use = $opData['input']['use']; + // add ns to ns array + if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ + $nsPrefix = 'ns' . rand(1000, 9999); + $this->wsdl->namespaces[$nsPrefix] = $namespace; + } + $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); + // serialize payload + if (is_string($params)) { + $this->debug("serializing param string for WSDL operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for WSDL operation $operation"); + $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = $this->wsdl->usedNamespaces; + if (isset($opData['input']['encodingStyle'])) { + $encodingStyle = $opData['input']['encodingStyle']; + } else { + $encodingStyle = ''; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if ($errstr = $this->wsdl->getError()) { + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + return false; + } + } elseif($this->endpointType == 'wsdl') { + // operation not in WSDL + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + $this->setError( 'operation '.$operation.' not present.'); + $this->debug("operation '$operation' not present."); + return false; + } else { + // no WSDL + //$this->namespaces['ns1'] = $namespace; + $nsPrefix = 'ns' . rand(1000, 9999); + // serialize + $payload = ''; + if (is_string($params)) { + $this->debug("serializing param string for operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for operation $operation"); + foreach($params as $k => $v){ + $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = array(); + if ($use == 'encoded') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } else { + $encodingStyle = ''; + } + } + // wrap RPC calls with method element + if ($style == 'rpc') { + if ($use == 'literal') { + $this->debug("wrapping RPC request with literal method element"); + if ($namespace) { + $payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>"; + } else { + $payload = "<$operation>" . $payload . "</$operation>"; + } + } else { + $this->debug("wrapping RPC request with encoded method element"); + if ($namespace) { + $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . + $payload . + "</$nsPrefix:$operation>"; + } else { + $payload = "<$operation>" . + $payload . + "</$operation>"; + } + } + } + // serialize envelope + $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); + $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); + $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); + // send + $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); + if($errstr = $this->getError()){ + $this->debug('Error: '.$errstr); + return false; + } else { + $this->return = $return; + $this->debug('sent message successfully and got a(n) '.gettype($return)); + $this->appendDebug('return=' . $this->varDump($return)); + + // fault? + if(is_array($return) && isset($return['faultcode'])){ + $this->debug('got fault'); + $this->setError($return['faultcode'].': '.$return['faultstring']); + $this->fault = true; + foreach($return as $k => $v){ + $this->$k = $v; + $this->debug("$k = $v<br>"); + } + return $return; + } elseif ($style == 'document') { + // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), + // we are only going to return the first part here...sorry about that + return $return; + } else { + // array of return values + if(is_array($return)){ + // multiple 'out' parameters, which we return wrapped up + // in the array + if(sizeof($return) > 1){ + return $return; + } + // single 'out' parameter (normally the return value) + $return = array_shift($return); + $this->debug('return shifted value: '); + $this->appendDebug($this->varDump($return)); + return $return; + // nothing returned (ie, echoVoid) + } else { + return ""; + } + } + } + } + + /** + * get available data pertaining to an operation + * + * @param string $operation operation name + * @return array array of data pertaining to the operation + * @access public + */ + function getOperationData($operation){ + if(isset($this->operations[$operation])){ + return $this->operations[$operation]; + } + $this->debug("No data for operation: $operation"); + } + + /** + * send the SOAP message + * + * Note: if the operation has multiple return values + * the return value of this method will be an array + * of those values. + * + * @param string $msg a SOAPx4 soapmsg object + * @param string $soapaction SOAPAction value + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @return mixed native PHP types. + * @access private + */ + function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { + $this->checkCookies(); + // detect transport + switch(true){ + // http(s) + case ereg('^http',$this->endpoint): + $this->debug('transporting via HTTP'); + if($this->persistentConnection == true && is_object($this->persistentConnection)){ + $http =& $this->persistentConnection; + } else { + $http = new soap_transport_http($this->endpoint); + if ($this->persistentConnection) { + $http->usePersistentConnection(); + } + } + $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); + $http->setSOAPAction($soapaction); + if($this->proxyhost && $this->proxyport){ + $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + if($this->authtype != '') { + $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); + } + if($this->http_encoding != ''){ + $http->setEncoding($this->http_encoding); + } + $this->debug('sending message, length='.strlen($msg)); + if(ereg('^http:',$this->endpoint)){ + //if(strpos($this->endpoint,'http:')){ + $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); + } elseif(ereg('^https',$this->endpoint)){ + //} elseif(strpos($this->endpoint,'https:')){ + //if(phpversion() == '4.3.0-dev'){ + //$response = $http->send($msg,$timeout,$response_timeout); + //$this->request = $http->outgoing_payload; + //$this->response = $http->incoming_payload; + //} else + $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); + } else { + $this->setError('no http/s in endpoint url'); + } + $this->request = $http->outgoing_payload; + $this->response = $http->incoming_payload; + $this->appendDebug($http->getDebug()); + $this->UpdateCookies($http->incoming_cookies); + + // save transport object if using persistent connections + if ($this->persistentConnection) { + $http->clearDebug(); + if (!is_object($this->persistentConnection)) { + $this->persistentConnection = $http; + } + } + + if($err = $http->getError()){ + $this->setError('HTTP Error: '.$err); + return false; + } elseif($this->getError()){ + return false; + } else { + $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); + return $this->parseResponse($http->incoming_headers, $this->responseData); + } + break; + default: + $this->setError('no transport found, or selected transport is not yet supported!'); + return false; + break; + } + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Response not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8); + // add parser debug data to our debug + $this->appendDebug($parser->getDebug()); + // if parse errors + if($errstr = $parser->getError()){ + $this->setError( $errstr); + // destroy the parser object + unset($parser); + return false; + } else { + // get SOAP headers + $this->responseHeaders = $parser->getHeaders(); + // get decoded message + $return = $parser->get_response(); + // add document for doclit support + $this->document = $parser->document; + // destroy the parser object + unset($parser); + // return decode message + return $return; + } + } + + /** + * sets the SOAP endpoint, which can override WSDL + * + * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override + * @access public + */ + function setEndpoint($endpoint) { + $this->forceEndpoint = $endpoint; + } + + /** + * set the SOAP headers + * + * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers + * @access public + */ + function setHeaders($headers){ + $this->requestHeaders = $headers; + } + + /** + * get the SOAP response headers (namespace resolution incomplete) + * + * @return string + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic|digest|certificate) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->certRequest = $certRequest; + } + + /** + * use HTTP encoding + * + * @param string $enc + * @access public + */ + function setHTTPEncoding($enc='gzip, deflate'){ + $this->http_encoding = $enc; + } + + /** + * use HTTP persistent connections if possible + * + * @access public + */ + function useHTTPPersistentConnection(){ + $this->persistentConnection = true; + } + + /** + * gets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style. + * Each call() can override this value. + * + * This is no longer used. + * + * @return boolean + * @access public + * @deprecated + */ + function getDefaultRpcParams() { + return $this->defaultRpcParams; + } + + /** + * sets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style + * Each call() can override this value. + * + * This is no longer used. + * + * @param boolean $rpcParams + * @access public + * @deprecated + */ + function setDefaultRpcParams($rpcParams) { + $this->defaultRpcParams = $rpcParams; + } + + /** + * dynamically creates an instance of a proxy class, + * allowing user to directly call methods from wsdl + * + * @return object soap_proxy object + * @access public + */ + function getProxy(){ + $r = rand(); + $evalStr = $this->_getProxyClassCode($r); + //$this->debug("proxy class: $evalStr"; + // eval the class + eval($evalStr); + // instantiate proxy object + eval("\$proxy = new soap_proxy_$r('');"); + // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice + $proxy->endpointType = 'wsdl'; + $proxy->wsdlFile = $this->wsdlFile; + $proxy->wsdl = $this->wsdl; + $proxy->operations = $this->operations; + $proxy->defaultRpcParams = $this->defaultRpcParams; + // transfer other state + $proxy->username = $this->username; + $proxy->password = $this->password; + $proxy->authtype = $this->authtype; + $proxy->proxyhost = $this->proxyhost; + $proxy->proxyport = $this->proxyport; + $proxy->proxyusername = $this->proxyusername; + $proxy->proxypassword = $this->proxypassword; + $proxy->timeout = $this->timeout; + $proxy->response_timeout = $this->response_timeout; + $proxy->http_encoding = $this->http_encoding; + $proxy->persistentConnection = $this->persistentConnection; + $proxy->requestHeaders = $this->requestHeaders; + $proxy->soap_defencoding = $this->soap_defencoding; + $proxy->endpoint = $this->endpoint; + $proxy->forceEndpoint = $this->forceEndpoint; + return $proxy; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access private + */ + function _getProxyClassCode($r) { + if ($this->endpointType != 'wsdl') { + $evalStr = 'A proxy can only be created for a WSDL client'; + $this->setError($evalStr); + return $evalStr; + } + $evalStr = ''; + foreach ($this->operations as $operation => $opData) { + if ($operation != '') { + // create param string and param comment string + if (sizeof($opData['input']['parts']) > 0) { + $paramStr = ''; + $paramArrayStr = ''; + $paramCommentStr = ''; + foreach ($opData['input']['parts'] as $name => $type) { + $paramStr .= "\$$name, "; + $paramArrayStr .= "'$name' => \$$name, "; + $paramCommentStr .= "$type \$$name, "; + } + $paramStr = substr($paramStr, 0, strlen($paramStr)-2); + $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); + $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); + } else { + $paramStr = ''; + $paramCommentStr = 'void'; + } + $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; + $evalStr .= "// $paramCommentStr + function " . str_replace('.', '__', $operation) . "($paramStr) { + \$params = array($paramArrayStr); + return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); + } + "; + unset($paramStr); + unset($paramCommentStr); + } + } + $evalStr = 'class soap_proxy_'.$r.' extends soapclient { + '.$evalStr.' +}'; + return $evalStr; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access public + */ + function getProxyClassCode() { + $r = rand(); + return $this->_getProxyClassCode($r); + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /* + * whether or not parser should decode utf8 element content + * + * @return always returns true + * @access public + */ + function decodeUTF8($bool){ + $this->decode_utf8 = $bool; + return true; + } + + /** + * adds a new Cookie into $this->cookies array + * + * @param string $name Cookie Name + * @param string $value Cookie Value + * @return if cookie-set was successful returns true, else false + * @access public + */ + function setCookie($name, $value) { + if (strlen($name) == 0) { + return false; + } + $this->cookies[] = array('name' => $name, 'value' => $value); + return true; + } + + /** + * gets all Cookies + * + * @return array with all internal cookies + * @access public + */ + function getCookies() { + return $this->cookies; + } + + /** + * checks all Cookies and delete those which are expired + * + * @return always return true + * @access private + */ + function checkCookies() { + if (sizeof($this->cookies) == 0) { + return true; + } + $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); + $curr_cookies = $this->cookies; + $this->cookies = array(); + foreach ($curr_cookies as $cookie) { + if (! is_array($cookie)) { + $this->debug('Remove cookie that is not an array'); + continue; + } + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) > time()) { + $this->cookies[] = $cookie; + } else { + $this->debug('Remove expired cookie ' . $cookie['name']); + } + } else { + $this->cookies[] = $cookie; + } + } + $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); + return true; + } + + /** + * updates the current cookies with a new set + * + * @param array $cookies new cookies with which to update current ones + * @return always return true + * @access private + */ + function UpdateCookies($cookies) { + if (sizeof($this->cookies) == 0) { + // no existing cookies: take whatever is new + if (sizeof($cookies) > 0) { + $this->debug('Setting new cookie(s)'); + $this->cookies = $cookies; + } + return true; + } + if (sizeof($cookies) == 0) { + // no new cookies: keep what we've got + return true; + } + // merge + foreach ($cookies as $newCookie) { + if (!is_array($newCookie)) { + continue; + } + if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { + continue; + } + $newName = $newCookie['name']; + + $found = false; + for ($i = 0; $i < count($this->cookies); $i++) { + $cookie = $this->cookies[$i]; + if (!is_array($cookie)) { + continue; + } + if (!isset($cookie['name'])) { + continue; + } + if ($newName != $cookie['name']) { + continue; + } + $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; + $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; + if ($newDomain != $domain) { + continue; + } + $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; + $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; + if ($newPath != $path) { + continue; + } + $this->cookies[$i] = $newCookie; + $found = true; + $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); + break; + } + if (! $found) { + $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); + $this->cookies[] = $newCookie; + } + } + return true; + } +} +?> diff --git a/htdocs/includes/nusoap/lib/nusoapmime.php b/htdocs/includes/nusoap/lib/nusoapmime.php index 7334c9a931777f8b91244bb7536b143052d94681..88fa9946be1b8f11d552c58eea3bb77186af2a89 100644 --- a/htdocs/includes/nusoap/lib/nusoapmime.php +++ b/htdocs/includes/nusoap/lib/nusoapmime.php @@ -1,478 +1,478 @@ -<?php -/* -$Id$ - -NuSOAP - Web Services Toolkit for PHP - -Copyright (c) 2002 NuSphere Corporation - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -If you have any questions or comments, please email: - -Dietrich Ayala -dietrich@ganx4.com -http://dietrich.ganx4.com/nusoap - -NuSphere Corporation -http://www.nusphere.com - -*/ - -/*require_once('nusoap.php');*/ -/* PEAR Mail_MIME library */ -require_once('Mail/mimeDecode.php'); -require_once('Mail/mimePart.php'); - -/** -* soapclientmime client supporting MIME attachments defined at -* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library. -* -* @author Scott Nichol <snichol@sourceforge.net> -* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list -* @version $Id$ -* @access public -*/ -class soapclientmime extends soapclient { - /** - * @var array Each array element in the return is an associative array with keys - * data, filename, contenttype, cid - * @access private - */ - var $requestAttachments = array(); - /** - * @var array Each array element in the return is an associative array with keys - * data, filename, contenttype, cid - * @access private - */ - var $responseAttachments; - /** - * @var string - * @access private - */ - var $mimeContentType; - - /** - * adds a MIME attachment to the current request. - * - * If the $data parameter contains an empty string, this method will read - * the contents of the file named by the $filename parameter. - * - * If the $cid parameter is false, this method will generate the cid. - * - * @param string $data The data of the attachment - * @param string $filename The filename of the attachment (default is empty string) - * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream) - * @param string $cid The content-id (cid) of the attachment (default is false) - * @return string The content-id (cid) of the attachment - * @access public - */ - function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) { - if (! $cid) { - $cid = md5(uniqid(time())); - } - - $info['data'] = $data; - $info['filename'] = $filename; - $info['contenttype'] = $contenttype; - $info['cid'] = $cid; - - $this->requestAttachments[] = $info; - - return $cid; - } - - /** - * clears the MIME attachments for the current request. - * - * @access public - */ - function clearAttachments() { - $this->requestAttachments = array(); - } - - /** - * gets the MIME attachments from the current response. - * - * Each array element in the return is an associative array with keys - * data, filename, contenttype, cid. These keys correspond to the parameters - * for addAttachment. - * - * @return array The attachments. - * @access public - */ - function getAttachments() { - return $this->responseAttachments; - } - - /** - * gets the HTTP body for the current request. - * - * @param string $soapmsg The SOAP payload - * @return string The HTTP body, which includes the SOAP payload - * @access private - */ - function getHTTPBody($soapmsg) { - if (count($this->requestAttachments) > 0) { - $params['content_type'] = 'multipart/related; type=text/xml'; - $mimeMessage =& new Mail_mimePart('', $params); - unset($params); - - $params['content_type'] = 'text/xml'; - $params['encoding'] = '8bit'; - $params['charset'] = $this->soap_defencoding; - $mimeMessage->addSubpart($soapmsg, $params); - - foreach ($this->requestAttachments as $att) { - unset($params); - - $params['content_type'] = $att['contenttype']; - $params['encoding'] = 'base64'; - $params['disposition'] = 'attachment'; - $params['dfilename'] = $att['filename']; - $params['cid'] = $att['cid']; - - if ($att['data'] == '' && $att['filename'] <> '') { - if ($fd = fopen($att['filename'], 'rb')) { - $data = fread($fd, filesize($att['filename'])); - fclose($fd); - } else { - $data = ''; - } - $mimeMessage->addSubpart($data, $params); - } else { - $mimeMessage->addSubpart($att['data'], $params); - } - } - - $output = $mimeMessage->encode(); - $mimeHeaders = $output['headers']; - - foreach ($mimeHeaders as $k => $v) { - $this->debug("MIME header $k: $v"); - if (strtolower($k) == 'content-type') { - // PHP header() seems to strip leading whitespace starting - // the second line, so force everything to one line - $this->mimeContentType = str_replace("\r\n", " ", $v); - } - } - - return $output['body']; - } - - return parent::getHTTPBody($soapmsg); - } - - /** - * gets the HTTP content type for the current request. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type for the current request. - * @access private - */ - function getHTTPContentType() { - if (count($this->requestAttachments) > 0) { - return $this->mimeContentType; - } - return parent::getHTTPContentType(); - } - - /** - * gets the HTTP content type charset for the current request. - * returns false for non-text content types. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type charset for the current request. - * @access private - */ - function getHTTPContentTypeCharset() { - if (count($this->requestAttachments) > 0) { - return false; - } - return parent::getHTTPContentTypeCharset(); - } - - /** - * processes SOAP message returned from server - * - * @param array $headers The HTTP headers - * @param string $data unprocessed response data from server - * @return mixed value of the message, decoded into a PHP type - * @access private - */ - function parseResponse($headers, $data) { - $this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']); - $this->responseAttachments = array(); - if (strstr($headers['content-type'], 'multipart/related')) { - $this->debug('Decode multipart/related'); - $input = ''; - foreach ($headers as $k => $v) { - $input .= "$k: $v\r\n"; - } - $params['input'] = $input . "\r\n" . $data; - $params['include_bodies'] = true; - $params['decode_bodies'] = true; - $params['decode_headers'] = true; - - $structure = Mail_mimeDecode::decode($params); - - foreach ($structure->parts as $part) { - if (!isset($part->disposition)) { - $this->debug('Have root part of type ' . $part->headers['content-type']); - $return = parent::parseResponse($part->headers, $part->body); - } else { - $this->debug('Have an attachment of type ' . $part->headers['content-type']); - $info['data'] = $part->body; - $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : ''; - $info['contenttype'] = $part->headers['content-type']; - $info['cid'] = $part->headers['content-id']; - $this->responseAttachments[] = $info; - } - } - - if (isset($return)) { - return $return; - } - - $this->setError('No root part found in multipart/related content'); - return; - } - $this->debug('Not multipart/related'); - return parent::parseResponse($headers, $data); - } -} - -/** -* nusoapservermime server supporting MIME attachments defined at -* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library. -* -* @author Scott Nichol <snichol@sourceforge.net> -* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list -* @version $Id$ -* @access public -*/ -class nusoapservermime extends soap_server { - /** - * @var array Each array element in the return is an associative array with keys - * data, filename, contenttype, cid - * @access private - */ - var $requestAttachments = array(); - /** - * @var array Each array element in the return is an associative array with keys - * data, filename, contenttype, cid - * @access private - */ - var $responseAttachments; - /** - * @var string - * @access private - */ - var $mimeContentType; - - /** - * adds a MIME attachment to the current response. - * - * If the $data parameter contains an empty string, this method will read - * the contents of the file named by the $filename parameter. - * - * If the $cid parameter is false, this method will generate the cid. - * - * @param string $data The data of the attachment - * @param string $filename The filename of the attachment (default is empty string) - * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream) - * @param string $cid The content-id (cid) of the attachment (default is false) - * @return string The content-id (cid) of the attachment - * @access public - */ - function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) { - if (! $cid) { - $cid = md5(uniqid(time())); - } - - $info['data'] = $data; - $info['filename'] = $filename; - $info['contenttype'] = $contenttype; - $info['cid'] = $cid; - - $this->responseAttachments[] = $info; - - return $cid; - } - - /** - * clears the MIME attachments for the current response. - * - * @access public - */ - function clearAttachments() { - $this->responseAttachments = array(); - } - - /** - * gets the MIME attachments from the current request. - * - * Each array element in the return is an associative array with keys - * data, filename, contenttype, cid. These keys correspond to the parameters - * for addAttachment. - * - * @return array The attachments. - * @access public - */ - function getAttachments() { - return $this->requestAttachments; - } - - /** - * gets the HTTP body for the current response. - * - * @param string $soapmsg The SOAP payload - * @return string The HTTP body, which includes the SOAP payload - * @access private - */ - function getHTTPBody($soapmsg) { - if (count($this->responseAttachments) > 0) { - $params['content_type'] = 'multipart/related; type=text/xml'; - $mimeMessage =& new Mail_mimePart('', $params); - unset($params); - - $params['content_type'] = 'text/xml'; - $params['encoding'] = '8bit'; - $params['charset'] = $this->soap_defencoding; - $mimeMessage->addSubpart($soapmsg, $params); - - foreach ($this->responseAttachments as $att) { - unset($params); - - $params['content_type'] = $att['contenttype']; - $params['encoding'] = 'base64'; - $params['disposition'] = 'attachment'; - $params['dfilename'] = $att['filename']; - $params['cid'] = $att['cid']; - - if ($att['data'] == '' && $att['filename'] <> '') { - if ($fd = fopen($att['filename'], 'rb')) { - $data = fread($fd, filesize($att['filename'])); - fclose($fd); - } else { - $data = ''; - } - $mimeMessage->addSubpart($data, $params); - } else { - $mimeMessage->addSubpart($att['data'], $params); - } - } - - $output = $mimeMessage->encode(); - $mimeHeaders = $output['headers']; - - foreach ($mimeHeaders as $k => $v) { - $this->debug("MIME header $k: $v"); - if (strtolower($k) == 'content-type') { - // PHP header() seems to strip leading whitespace starting - // the second line, so force everything to one line - $this->mimeContentType = str_replace("\r\n", " ", $v); - } - } - - return $output['body']; - } - - return parent::getHTTPBody($soapmsg); - } - - /** - * gets the HTTP content type for the current response. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type for the current response. - * @access private - */ - function getHTTPContentType() { - if (count($this->responseAttachments) > 0) { - return $this->mimeContentType; - } - return parent::getHTTPContentType(); - } - - /** - * gets the HTTP content type charset for the current response. - * returns false for non-text content types. - * - * Note: getHTTPBody must be called before this. - * - * @return string the HTTP content type charset for the current response. - * @access private - */ - function getHTTPContentTypeCharset() { - if (count($this->responseAttachments) > 0) { - return false; - } - return parent::getHTTPContentTypeCharset(); - } - - /** - * processes SOAP message received from client - * - * @param array $headers The HTTP headers - * @param string $data unprocessed request data from client - * @return mixed value of the message, decoded into a PHP type - * @access private - */ - function parseRequest($headers, $data) { - $this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']); - $this->requestAttachments = array(); - if (strstr($headers['content-type'], 'multipart/related')) { - $this->debug('Decode multipart/related'); - $input = ''; - foreach ($headers as $k => $v) { - $input .= "$k: $v\r\n"; - } - $params['input'] = $input . "\r\n" . $data; - $params['include_bodies'] = true; - $params['decode_bodies'] = true; - $params['decode_headers'] = true; - - $structure = Mail_mimeDecode::decode($params); - - foreach ($structure->parts as $part) { - if (!isset($part->disposition)) { - $this->debug('Have root part of type ' . $part->headers['content-type']); - $return = parent::parseRequest($part->headers, $part->body); - } else { - $this->debug('Have an attachment of type ' . $part->headers['content-type']); - $info['data'] = $part->body; - $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : ''; - $info['contenttype'] = $part->headers['content-type']; - $info['cid'] = $part->headers['content-id']; - $this->requestAttachments[] = $info; - } - } - - if (isset($return)) { - return $return; - } - - $this->setError('No root part found in multipart/related content'); - return; - } - $this->debug('Not multipart/related'); - return parent::parseRequest($headers, $data); - } -} -?> +<?php +/* +$Id$ + +NuSOAP - Web Services Toolkit for PHP + +Copyright (c) 2002 NuSphere Corporation + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you have any questions or comments, please email: + +Dietrich Ayala +dietrich@ganx4.com +http://dietrich.ganx4.com/nusoap + +NuSphere Corporation +http://www.nusphere.com + +*/ + +/*require_once('nusoap.php');*/ +/* PEAR Mail_MIME library */ +require_once('Mail/mimeDecode.php'); +require_once('Mail/mimePart.php'); + +/** +* soapclientmime client supporting MIME attachments defined at +* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library. +* +* @author Scott Nichol <snichol@sourceforge.net> +* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list +* @version $Id$ +* @access public +*/ +class soapclientmime extends soapclient { + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $requestAttachments = array(); + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $responseAttachments; + /** + * @var string + * @access private + */ + var $mimeContentType; + + /** + * adds a MIME attachment to the current request. + * + * If the $data parameter contains an empty string, this method will read + * the contents of the file named by the $filename parameter. + * + * If the $cid parameter is false, this method will generate the cid. + * + * @param string $data The data of the attachment + * @param string $filename The filename of the attachment (default is empty string) + * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream) + * @param string $cid The content-id (cid) of the attachment (default is false) + * @return string The content-id (cid) of the attachment + * @access public + */ + function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) { + if (! $cid) { + $cid = md5(uniqid(time())); + } + + $info['data'] = $data; + $info['filename'] = $filename; + $info['contenttype'] = $contenttype; + $info['cid'] = $cid; + + $this->requestAttachments[] = $info; + + return $cid; + } + + /** + * clears the MIME attachments for the current request. + * + * @access public + */ + function clearAttachments() { + $this->requestAttachments = array(); + } + + /** + * gets the MIME attachments from the current response. + * + * Each array element in the return is an associative array with keys + * data, filename, contenttype, cid. These keys correspond to the parameters + * for addAttachment. + * + * @return array The attachments. + * @access public + */ + function getAttachments() { + return $this->responseAttachments; + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + if (count($this->requestAttachments) > 0) { + $params['content_type'] = 'multipart/related; type=text/xml'; + $mimeMessage =& new Mail_mimePart('', $params); + unset($params); + + $params['content_type'] = 'text/xml'; + $params['encoding'] = '8bit'; + $params['charset'] = $this->soap_defencoding; + $mimeMessage->addSubpart($soapmsg, $params); + + foreach ($this->requestAttachments as $att) { + unset($params); + + $params['content_type'] = $att['contenttype']; + $params['encoding'] = 'base64'; + $params['disposition'] = 'attachment'; + $params['dfilename'] = $att['filename']; + $params['cid'] = $att['cid']; + + if ($att['data'] == '' && $att['filename'] <> '') { + if ($fd = fopen($att['filename'], 'rb')) { + $data = fread($fd, filesize($att['filename'])); + fclose($fd); + } else { + $data = ''; + } + $mimeMessage->addSubpart($data, $params); + } else { + $mimeMessage->addSubpart($att['data'], $params); + } + } + + $output = $mimeMessage->encode(); + $mimeHeaders = $output['headers']; + + foreach ($mimeHeaders as $k => $v) { + $this->debug("MIME header $k: $v"); + if (strtolower($k) == 'content-type') { + // PHP header() seems to strip leading whitespace starting + // the second line, so force everything to one line + $this->mimeContentType = str_replace("\r\n", " ", $v); + } + } + + return $output['body']; + } + + return parent::getHTTPBody($soapmsg); + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + if (count($this->requestAttachments) > 0) { + return $this->mimeContentType; + } + return parent::getHTTPContentType(); + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + if (count($this->requestAttachments) > 0) { + return false; + } + return parent::getHTTPContentTypeCharset(); + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']); + $this->responseAttachments = array(); + if (strstr($headers['content-type'], 'multipart/related')) { + $this->debug('Decode multipart/related'); + $input = ''; + foreach ($headers as $k => $v) { + $input .= "$k: $v\r\n"; + } + $params['input'] = $input . "\r\n" . $data; + $params['include_bodies'] = true; + $params['decode_bodies'] = true; + $params['decode_headers'] = true; + + $structure = Mail_mimeDecode::decode($params); + + foreach ($structure->parts as $part) { + if (!isset($part->disposition)) { + $this->debug('Have root part of type ' . $part->headers['content-type']); + $return = parent::parseResponse($part->headers, $part->body); + } else { + $this->debug('Have an attachment of type ' . $part->headers['content-type']); + $info['data'] = $part->body; + $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : ''; + $info['contenttype'] = $part->headers['content-type']; + $info['cid'] = $part->headers['content-id']; + $this->responseAttachments[] = $info; + } + } + + if (isset($return)) { + return $return; + } + + $this->setError('No root part found in multipart/related content'); + return; + } + $this->debug('Not multipart/related'); + return parent::parseResponse($headers, $data); + } +} + +/** +* nusoapservermime server supporting MIME attachments defined at +* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library. +* +* @author Scott Nichol <snichol@sourceforge.net> +* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list +* @version $Id$ +* @access public +*/ +class nusoapservermime extends soap_server { + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $requestAttachments = array(); + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $responseAttachments; + /** + * @var string + * @access private + */ + var $mimeContentType; + + /** + * adds a MIME attachment to the current response. + * + * If the $data parameter contains an empty string, this method will read + * the contents of the file named by the $filename parameter. + * + * If the $cid parameter is false, this method will generate the cid. + * + * @param string $data The data of the attachment + * @param string $filename The filename of the attachment (default is empty string) + * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream) + * @param string $cid The content-id (cid) of the attachment (default is false) + * @return string The content-id (cid) of the attachment + * @access public + */ + function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) { + if (! $cid) { + $cid = md5(uniqid(time())); + } + + $info['data'] = $data; + $info['filename'] = $filename; + $info['contenttype'] = $contenttype; + $info['cid'] = $cid; + + $this->responseAttachments[] = $info; + + return $cid; + } + + /** + * clears the MIME attachments for the current response. + * + * @access public + */ + function clearAttachments() { + $this->responseAttachments = array(); + } + + /** + * gets the MIME attachments from the current request. + * + * Each array element in the return is an associative array with keys + * data, filename, contenttype, cid. These keys correspond to the parameters + * for addAttachment. + * + * @return array The attachments. + * @access public + */ + function getAttachments() { + return $this->requestAttachments; + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + if (count($this->responseAttachments) > 0) { + $params['content_type'] = 'multipart/related; type=text/xml'; + $mimeMessage =& new Mail_mimePart('', $params); + unset($params); + + $params['content_type'] = 'text/xml'; + $params['encoding'] = '8bit'; + $params['charset'] = $this->soap_defencoding; + $mimeMessage->addSubpart($soapmsg, $params); + + foreach ($this->responseAttachments as $att) { + unset($params); + + $params['content_type'] = $att['contenttype']; + $params['encoding'] = 'base64'; + $params['disposition'] = 'attachment'; + $params['dfilename'] = $att['filename']; + $params['cid'] = $att['cid']; + + if ($att['data'] == '' && $att['filename'] <> '') { + if ($fd = fopen($att['filename'], 'rb')) { + $data = fread($fd, filesize($att['filename'])); + fclose($fd); + } else { + $data = ''; + } + $mimeMessage->addSubpart($data, $params); + } else { + $mimeMessage->addSubpart($att['data'], $params); + } + } + + $output = $mimeMessage->encode(); + $mimeHeaders = $output['headers']; + + foreach ($mimeHeaders as $k => $v) { + $this->debug("MIME header $k: $v"); + if (strtolower($k) == 'content-type') { + // PHP header() seems to strip leading whitespace starting + // the second line, so force everything to one line + $this->mimeContentType = str_replace("\r\n", " ", $v); + } + } + + return $output['body']; + } + + return parent::getHTTPBody($soapmsg); + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + if (count($this->responseAttachments) > 0) { + return $this->mimeContentType; + } + return parent::getHTTPContentType(); + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + if (count($this->responseAttachments) > 0) { + return false; + } + return parent::getHTTPContentTypeCharset(); + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']); + $this->requestAttachments = array(); + if (strstr($headers['content-type'], 'multipart/related')) { + $this->debug('Decode multipart/related'); + $input = ''; + foreach ($headers as $k => $v) { + $input .= "$k: $v\r\n"; + } + $params['input'] = $input . "\r\n" . $data; + $params['include_bodies'] = true; + $params['decode_bodies'] = true; + $params['decode_headers'] = true; + + $structure = Mail_mimeDecode::decode($params); + + foreach ($structure->parts as $part) { + if (!isset($part->disposition)) { + $this->debug('Have root part of type ' . $part->headers['content-type']); + $return = parent::parseRequest($part->headers, $part->body); + } else { + $this->debug('Have an attachment of type ' . $part->headers['content-type']); + $info['data'] = $part->body; + $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : ''; + $info['contenttype'] = $part->headers['content-type']; + $info['cid'] = $part->headers['content-id']; + $this->requestAttachments[] = $info; + } + } + + if (isset($return)) { + return $return; + } + + $this->setError('No root part found in multipart/related content'); + return; + } + $this->debug('Not multipart/related'); + return parent::parseRequest($headers, $data); + } +} +?> diff --git a/htdocs/includes/phplot5/.cvsignore b/htdocs/includes/phplot5/.cvsignore index 6554a8fb276f55a8ee84641f55af62594bb17e04..9204e9e8ec20ca0deeee59cfd73942795a07ceb1 100644 --- a/htdocs/includes/phplot5/.cvsignore +++ b/htdocs/includes/phplot5/.cvsignore @@ -1,2 +1,2 @@ -doc -examples +doc +examples diff --git a/htdocs/includes/scriptaculous/.cvsignore b/htdocs/includes/scriptaculous/.cvsignore index 77356c31404cfbc88ab78de4025ebd609c022927..9daeafb9864cf43055ae93beb0afd6c7d144bfa4 100644 --- a/htdocs/includes/scriptaculous/.cvsignore +++ b/htdocs/includes/scriptaculous/.cvsignore @@ -1 +1 @@ -test +test diff --git a/htdocs/langs/fr_BE/html/gpl.txt b/htdocs/langs/fr_BE/html/gpl.txt index 63329a6aa748bff106c11f066ad8f1f381772be4..ed06504c98314dea9355204775f127fdfde81c2f 100644 --- a/htdocs/langs/fr_BE/html/gpl.txt +++ b/htdocs/langs/fr_BE/html/gpl.txt @@ -1,390 +1,390 @@ GNU GENERAL PUBLIC LICENSE - -Traduction de R.Cougnec et M.Makar�vitch - -Introduction : -This is an unofficial translation of the GNU General Public License into -French. It was not published by the Free Software Foundation, and does not -legally state the distribution terms for software that uses the GNU -GPL--only the original English text of the GNU GPL does that. However, we -hope that this translation will help French speakers understand the GNU GPL -better. - -Voici une adaptation non officielle de la Licence Publique G�n�rale du -projet GNU. Elle n'a pas �t� publi�e par la Free Software Foundation et son -contenu n'a aucune port�e l�gale car seule la version anglaise de ce -document d�taille le mode de distribution des logiciels sous GNU GPL. Nous -esp�rons cependant qu'elle permettra aux francophones de mieux comprendre -la GPL. - - -Licence Publique G�n�rale GNU Version 2, Juin 1991- - -Copyright (c) Free Software Foundation, Inc. -59 Temple Place, Suite 330, -Boston, MA 02111-1307 -�tats-Unis, 1989, 1991. -La copie et la distribution de copies exactes de ce document sont -autoris�es, mais aucune modification n'est permise. - - Pr�ambule - -Les licences d'utilisation de la plupart des programmes sont d�finies pour -limiter ou supprimer toute libert� � l'utilisateur. � l'inverse, la -Licence Publique G�n�rale (General Public License) est destin�e � vous -garantir la libert� de partager et de modifier les logiciels libres, et de -s'assurer que ces logiciels sont effectivement accessibles � tout -utilisateur. - -Cette Licence Publique G�n�rale s'applique � la plupart des programmes de -la Free Software Foundation, comme � tout autre programme dont l'auteur -l'aura d�cid� (d'autres logiciels de la FSF sont couverts pour leur part -par la Licence Publique G�n�rale pour Biblioth�ques GNU (LGPL)). Vous -pouvez aussi appliquer les termes de cette Licence � vos propres -programmes, si vous le d�sirez. - - _Libert� des logiciels ne signifie pas n�cessairement -gratuit�. Notre Licence est con�ue pour vous assurer la libert� de -distribuer des copies des programmes, gratuitement ou non, de recevoir le -code source ou de pouvoir l'obtenir, de modifier les programmes ou d'en -utiliser des �l�ments dans de nouveaux programmes libres, en sachant que -vous y �tes autoris�. - -Afin de garantir ces droits, nous avons d� introduire des restrictions -interdisant � quiconque de vous les refuser ou de vous demander d'y -renoncer. Ces restrictions vous imposent en retour certaines obligations si -vous distribuez ou modifiez des copies de programmes prot�g�s par la -Licence. En d'autre termes, il vous incombera en ce cas de : - - -transmettre aux destinataires tous les droits que vous poss�dez, - -exp�dier aux destinataires le code source ou bien tenir celui-ci � - leur disposition, - -leur remettre cette Licence afin qu'ils prennent connaissance de - leurs droits. - - -Nous prot�geons vos droits de deux fa�ons : d'abord par le copyright -du logiciel, ensuite par la remise de cette Licence qui vous autorise -l�galement � copier, distribuer et/ou modifier le logiciel. - -En outre, pour prot�ger chaque auteur ainsi que la FSF, nous affirmons -solennellement que le programme concern� ne fait l'objet d'aucune garantie. -Si un tiers le modifie puis le redistribue, tous ceux qui en recevront une -copie doivent savoir qu'il ne s'agit pas de l'original afin qu'une copie -d�fectueuse n'entache pas la r�putation de l'auteur du logiciel. - -Enfin, tout programme libre est sans cesse menac� par des d�p�ts de -brevets. Nous souhaitons � tout prix �viter que des distributeurs puissent -d�poser des brevets sur les Logiciels Libres pour leur propre compte. Pour -�viter cela, nous stipulons bien que tout d�p�t �ventuel de brevet doit -accorder express�ment � tout un chacun le libre usage du produit. - -Les dispositions pr�cises et les conditions de copie, de distribution et de -modification de nos logiciels sont les suivantes : - - Stipulations et conditions relatives � la copie, la distribution et la modification - - - _Article 0. - La pr�sente Licence s'applique � tout Programme (ou autre travail) o� - figure une note, plac�e par le d�tenteur des droits, stipulant que ledit - Programme ou travail peut �tre distribu� selon les termes de la pr�sente - Licence. Le terme Programme d�signe aussi bien le Programme - lui-m�me que tout travail qui en est d�riv� selon la loi, c'est-�-dire - tout ouvrage reproduisant le Programme ou une partie de celui-ci, � - l'identique ou bien modifi�, et/ou traduit dans une autre langue (la - traduction est consid�r�e comme une modification). Chaque personne - concern�e par la Licence Publique G�n�rale sera d�sign�e par le terme - Vous. - - Les activit�s autres que copie, distribution et modification ne sont pas - couvertes par la pr�sente Licence et sortent de son cadre. Rien ne - restreint l'utilisation du Programme et les donn�es issues de celui-ci ne - sont couvertes que si leur contenu constitue un travail bas� sur le - logiciel (ind�pendemment du fait d'avoir �t� r�alis� en lan�ant le - Programme). Tout d�pend de ce que le Programme est cens� produire. - - _Article 1. - Vous pouvez copier et distribuer des copies conformes du code source du - Programme, tel que Vous l'avez re�u, sur n'importe quel support, � - condition de placer sur chaque copie un copyright appropri� et une - restriction de garantie, de ne pas modifier ou omettre toutes les - stipulations se r�f�rant � la pr�sente Licence et � la limitation de - garantie, et de fournir avec toute copie du Programme un exemplaire de la - Licence. - - Vous pouvez demander une r�tribution financi�re pour la r�alisation de la - copie et demeurez libre de proposer une garantie assur�e par vos soins, - moyennant finances. - - _Article 2. - Vous pouvez modifier votre copie ou vos copies du Programme ou partie de - celui-ci, ou d'un travail bas� sur ce Programme, et copier et distribuer - ces modifications selon les termes de l'article 1, � condition de Vous - conformer �galement aux conditions suivantes : - - - a) Ajouter aux fichiers modifi�s l'indication tr�s claire des - modifications effectu�es, ainsi que la date de chaque changement. - - b) Distribuer sous les termes de la Licence Publique G�n�rale - l'ensemble de toute r�alisation contenant tout ou partie du - Programme, avec ou sans modifications. - c) Si le Programme modifi� lit des commandes de mani�re interactive - lors de son ex�cution, faire en sorte qu'il affiche, lors d'une - invocation ordinaire, le copyright appropri� en indiquant - clairement la limitation de garantie (ou la garantie que Vous Vous - engagez � fournir Vous-m�me), qu'il stipule que tout utilisateur - peut librement redistribuer le Programme selon les conditions de la - Licence Publique G�n�rale GNU, et qu'il montre � tout utilisateur - comment lire une copie de celle-ci (exception : si le - Programme original est interactif mais n'affiche pas un tel - message en temps normal, tout travail d�riv� de ce Programme ne - sera pas non plus contraint de l'afficher). - - Toutes ces conditions s'appliquent � l'ensemble des modifications. Si des - �l�ments identifiables de ce travail ne sont pas d�riv�s du Programme - et peuvent �tre raisonnablement consid�r�s comme ind�pendants, la - pr�sente Licence ne s'applique pas � ces �l�ments lorsque Vous les - distribuez seuls. - Mais, si Vous distribuez ces m�mes �l�ments comme partie d'un ensemble - coh�rent dont le reste est bas� sur un Programme soumis � la Licence, ils - lui sont �galement soumis, et la Licence s'�tend ainsi � l'ensemble du - produit, quel qu'en soit l'auteur. - - Cet article n'a pas pour but de s'approprier ou de contester vos - droits sur un travail enti�rement r�alis� par Vous, mais plut�t - d'ouvrir droit � un contr�le de la libre distribution de tout travail - d�riv� ou collectif bas� sur le Programme. - - En outre, toute fusion d'un autre travail, non bas� sur le Programme, - avec le Programme (ou avec un travail d�riv� de ce dernier), - effectu�e sur un support de stockage ou de distribution, ne fait pas - tomber cet autre travail sous le contr�le de la Licence. - - _Article 3. - Vous pouvez copier et distribuer le Programme (ou tout travail d�riv� - selon les conditions �nonc�es dans l'article 1) sous forme de code - objet ou ex�cutable, selon les termes des articles 0 et 1, � - condition de respecter les clauses suivantes : - - - a) Fournir le code source complet du Programme, - sous une forme lisible par un ordinateur et selon les termes des - articles 0 et 1, sur un support habituellement utilis� pour - l'�change de donn�es ou, - - b) Faire une offre �crite, valable pendant au moins trois ans, - pr�voyant de donner � tout tiers qui en fera la demande une copie, - sous forme lisible par un ordinateur, du code source correspondant, - pour un tarif n'exc�dant pas le co�t de la copie, selon - les termes des articles 0 et 1, sur un support couramment utilis� - pour l'�change de donn�es informatiques ou, - - c) Informer le destinataire de l'endroit o� le code source peut - �tre obtenu (cette solution n'est recevable que dans le cas d'une - distribution non commerciale, et uniquement si Vous avez re�u le - Programme sous forme de code objet ou ex�cutable avec l'offre - pr�vue � l'alin�a b ci-dessus). - - - Le code source d'un travail d�signe la forme de cet ouvrage sous laquelle - les modifications sont les plus ais�es. Sont ainsi d�sign�s la totalit� - du code source de tous les modules composant un Programme ex�cutable, de - m�me que tout fichier de d�finition associ�, ainsi que les scripts - utilis�s pour effectuer la compilation et l'installation du Programme - ex�cutable. Toutefois, l'environnement standard de d�veloppement du - syst�me d'exploitation mis en oeuvre (source ou binaire) -- compilateurs, - biblioth�ques, noyau, etc. -- constitue une exception, sauf si ces - �l�ments sont diffus�s en m�me temps que le Programme ex�cutable. - - Si la distribution de l'ex�cutable ou du code objet consiste � offrir un - acc�s permettant de copier le Programme depuis un endroit particulier, - l'offre d'un acc�s �quivalent pour se procurer le code source au m�me - endroit est consid�r� comme une distribution de ce code source, m�me si - l'utilisateur choisit de ne pas profiter de cette offre. - - _Article 4. - Vous ne pouvez pas copier, modifier, c�der, d�poser ou distribuer le - Programme d'une autre mani�re que l'autorise la Licence Publique G�n�rale. - Toute tentative de ce type annule imm�diatement vos droits d'utilisation du - Programme sous cette Licence. Toutefois, les tiers ayant re�u de Vous - des copies du Programme ou le droit d'utiliser ces copies continueront � - b�n�ficier de leur droit d'utilisation tant qu'ils respecteront pleinement - les conditions de la Licence. - - _Article 5. - Ne l'ayant pas sign�e, Vous n'�tes pas oblig� d'accepter cette - Licence. Cependant, rien d'autre ne Vous autorise � modifier ou distribuer - le Programme ou quelque travaux d�riv�s : la loi l'interdit tant que Vous - n'acceptez pas les termes de cette Licence. En cons�quence, en modifiant - ou en distribuant le Programme (ou tout travail bas� sur lui), Vous - acceptez implicitement tous les termes et conditions de cette Licence. - - _Article 6. - La diffusion d'un Programme (ou de tout travail d�riv�) suppose l'envoi - simultan� d'une licence autorisant la copie, la distribution ou la - modification du Programme, aux termes et conditions de la Licence. Vous - n'avez pas le droit d'imposer de restrictions suppl�mentaires aux droits - transmis au destinataire. Vous n'�tes pas responsable du respect de la - Licence par un tiers. - - _Article 7. - Si, � la suite d'une d�cision de Justice, d'une plainte en contrefa�on ou - pour toute autre raison (li�e ou non � la contrefa�on), des conditions Vous - sont impos�es (que ce soit par ordonnance, accord amiable ou autre) qui se - r�v�lent incompatibles avec les termes de la pr�sente Licence, Vous n'�tes - pas pour autant d�gag� des obligations li�es � celle-ci : si Vous ne - pouvez concilier vos obligations l�gales ou autres avec les conditions de - cette Licence, Vous ne devez pas distribuer le Programme. - - Si une partie quelconque de cet article est invalid�e ou inapplicable - pour quelque raison que ce soit, le reste de l'article continue de - s'appliquer et l'int�gralit� de l'article s'appliquera en toute autre - circonstance. - - Le pr�sent article n'a pas pour but de Vous pousser � enfreindre des - droits ou des dispositions l�gales ni en contester la validit� ; - son seul objectif est de prot�ger l'int�grit� du syst�me de - distribution du Logiciel Libre. De nombreuses personnes ont - g�n�reusement contribu� � la large gamme de Programmes distribu�e - de cette fa�on en toute confiance il appartient � chaque - auteur/donateur de d�cider de diffuser ses Programmes selon les crit�res - de son choix. - - _Article 8. - Si la distribution et/ou l'utilisation du Programme est limit�e dans - certains pays par des brevets ou des droits sur des interfaces, le - d�tenteur original des droits qui place le Programme sous la Licence - Publique G�n�rale peut ajouter explicitement une clause de limitation - g�ographique excluant ces pays. Dans ce cas, cette clause devient une - partie int�grante de la Licence. - - _Article 9. - La Free Software Foundation se r�serve le droit de publier p�riodiquement - des mises � jour ou de nouvelles versions de la Licence. R�dig�es dans le - m�me esprit que la pr�sente version, elles seront cependant susceptibles - d'en modifier certains d�tails � mesure que de nouveaux probl�mes se font - jour. - - Chaque version poss�de un num�ro distinct. Si le Programme pr�cise un - num�ro de version de cette Licence et � toute version ult�rieure �, Vous - avez le choix de suivre les termes et conditions de cette version ou de - toute autre version plus r�cente publi�e par la Free Software Foundation. - Si le Programme ne sp�cifie aucun num�ro de version, Vous pouvez alors - choisir l'une quelconque des versions publi�es par la Free Software - Foundation. - - - _Article 10. - Si Vous d�sirez incorporer des �l�ments du Programme dans d'autres - Programmes libres dont les conditions de distribution diff�rent, Vous devez - �crire � l'auteur pour lui en demander la permission. Pour ce qui est des - Programmes directement d�pos�s par la Free Software Foundation, - �crivez-nous : une exception est toujours envisageable. Notre d�cision - sera bas�e sur notre volont� de pr�server la libert� de notre Programme ou - de ses d�riv�s et celle de promouvoir le partage et la r�utilisation du - logiciel en g�n�ral. - - - LIMITATION DE GARANTIE - - - _Article 11. - - Parce que l'utilisation de ce Programme est libre et gratuite, aucune - garantie n'est fournie, comme le permet la loi. Sauf mention �crite, les - d�tenteurs du copyright et/ou les tiers fournissent le Programme en l'�tat, - sans aucune sorte de garantie explicite ou implicite, y compris les - garanties de commercialisation ou d'adaptation dans un but - particulier. Vous assumez tous les risques quant � la qualit� et aux effets - du Programme. Si le Programme est d�fectueux, Vous assumez le co�t de tous - les services, corrections ou r�parations n�cessaires. - - - _Article 12. - Sauf lorsqu'explicitement pr�vu par la Loi ou accept� par �crit, ni le - d�tenteur des droits, ni quiconque autoris� � modifier et/ou redistribuer - le Programme comme il est permis ci-dessus ne pourra �tre tenu pour - responsable de tout dommage direct, indirect, secondaire ou accessoire - (pertes financi�res dues au manque � gagner, � l'interruption d'activit�s - ou � la perte de donn�es, etc., d�coulant de l'utilisation du Programme ou - de l'impossibilit� d'utiliser celui-ci). - - - - FIN DES TERMES ET CONDITIONS - - Comment appliquer ces directives � vos nouveaux programmes - -Si vous d�veloppez un nouveau programme et d�sirez en faire b�n�ficier tout -un chacun, la meilleure m�thode est d'en faire un Logiciel Libre que tout -le monde pourra redistribuer et modifier selon les termes de la Licence -Publique G�n�rale. - -Pour cela, ins�rez les indications suivantes dans votre programme (il est -pr�f�rable et plus s�r de les faire figurer au d�but de chaque fichier -source dans tous les cas, chaque module source devra comporter au -minimum la ligne de � copyright � et indiquer o� r�sident toutes les -autres indications): - - -((une ligne pour donner le nom du programme et donner une id�e de -sa finalit�)) -Copyright (C) 19xx ((nom de l'auteur)) - -Ce programme est libre, vous pouvez le redistribuer et/ou le modifier -selon les termes de la Licence Publique G�n�rale GNU publi�e par la -Free Software Foundation (version 2 ou bien toute autre version -ult�rieure choisie par vous). - -Ce programme est distribu� car potentiellement utile, mais SANS AUCUNE -GARANTIE, ni explicite ni implicite, y compris les garanties de -commercialisation ou d'adaptation dans un but sp�cifique. -Reportez-vous � la Licence Publique G�n�rale GNU pour plus de d�tails. - -Vous devez avoir re�u une copie de la Licence Publique G�n�rale GNU -en m�me temps que ce programme si ce n'est pas le cas, �crivez � la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, �tats-Unis. - - -Ajoutez �galement votre adresse �lectronique, le cas �ch�ant, ainsi que -votre adresse postale. - -Si le programme est interactif, faites-lui afficher un court avertissement -du type de celui-ci � chaque invocation: - - -...(nom du programme) version 69, Copyright (C) 19aa nom de l'auteur - -...(nom du programme) est fourni sans AUCUNE GARANTIE. -Pour plus de d�tails, tapez `g'. - -Ce programme est libre et vous �tes encourag� � le redistribuer -sous certaines conditions tapez `c' pour plus de d�tails. - -Les commandes hypoth�tiques `g' et `c' doivent afficher les sections -appropri�es de la Licence Publique G�n�rale GNU. Bien entendu, vous pouvez -implanter ces commandes comme bon vous semble : options dans un menu, -ou bien accessibles d'un clic de souris, etc., tout d�pend de votre -programme. - -Si vous officiez en tant que programmeur, n'omettez pas de demander � votre -employeur, votre �tablissement scolaire ou autres de signer une d�charge -stipulant leur renoncement aux droits qu'ils pourraient avoir sur le -programme: -> -...((employeur, �cole...)) d�clare par la pr�sente ne pas revendiquer -de droits sur le programme � (nom du programme) � r�alis� par ...((nom de -l'auteur)). - -((signature du responsable)), ...((date)), -...((nom et qualit� du responsable)). - -La Licence Publique G�n�rale ne permet pas d'inclure votre programme dans -des logiciels sous licence commerciale sp�cifique. Si votre programme est -une fonction de biblioth�que, vous jugerez probablement plus judicieux de -le faire relever de la Licence G�n�rale de Biblioth�que GNU (LGPL) plut�t -que de la pr�sente. - + +Traduction de R.Cougnec et M.Makar�vitch + +Introduction : +This is an unofficial translation of the GNU General Public License into +French. It was not published by the Free Software Foundation, and does not +legally state the distribution terms for software that uses the GNU +GPL--only the original English text of the GNU GPL does that. However, we +hope that this translation will help French speakers understand the GNU GPL +better. + +Voici une adaptation non officielle de la Licence Publique G�n�rale du +projet GNU. Elle n'a pas �t� publi�e par la Free Software Foundation et son +contenu n'a aucune port�e l�gale car seule la version anglaise de ce +document d�taille le mode de distribution des logiciels sous GNU GPL. Nous +esp�rons cependant qu'elle permettra aux francophones de mieux comprendre +la GPL. + + -Licence Publique G�n�rale GNU Version 2, Juin 1991- + +Copyright (c) Free Software Foundation, Inc. +59 Temple Place, Suite 330, +Boston, MA 02111-1307 +�tats-Unis, 1989, 1991. +La copie et la distribution de copies exactes de ce document sont +autoris�es, mais aucune modification n'est permise. + + Pr�ambule + +Les licences d'utilisation de la plupart des programmes sont d�finies pour +limiter ou supprimer toute libert� � l'utilisateur. � l'inverse, la +Licence Publique G�n�rale (General Public License) est destin�e � vous +garantir la libert� de partager et de modifier les logiciels libres, et de +s'assurer que ces logiciels sont effectivement accessibles � tout +utilisateur. + +Cette Licence Publique G�n�rale s'applique � la plupart des programmes de +la Free Software Foundation, comme � tout autre programme dont l'auteur +l'aura d�cid� (d'autres logiciels de la FSF sont couverts pour leur part +par la Licence Publique G�n�rale pour Biblioth�ques GNU (LGPL)). Vous +pouvez aussi appliquer les termes de cette Licence � vos propres +programmes, si vous le d�sirez. + + _Libert� des logiciels ne signifie pas n�cessairement +gratuit�. Notre Licence est con�ue pour vous assurer la libert� de +distribuer des copies des programmes, gratuitement ou non, de recevoir le +code source ou de pouvoir l'obtenir, de modifier les programmes ou d'en +utiliser des �l�ments dans de nouveaux programmes libres, en sachant que +vous y �tes autoris�. + +Afin de garantir ces droits, nous avons d� introduire des restrictions +interdisant � quiconque de vous les refuser ou de vous demander d'y +renoncer. Ces restrictions vous imposent en retour certaines obligations si +vous distribuez ou modifiez des copies de programmes prot�g�s par la +Licence. En d'autre termes, il vous incombera en ce cas de : + + -transmettre aux destinataires tous les droits que vous poss�dez, + -exp�dier aux destinataires le code source ou bien tenir celui-ci � + leur disposition, + -leur remettre cette Licence afin qu'ils prennent connaissance de + leurs droits. + + +Nous prot�geons vos droits de deux fa�ons : d'abord par le copyright +du logiciel, ensuite par la remise de cette Licence qui vous autorise +l�galement � copier, distribuer et/ou modifier le logiciel. + +En outre, pour prot�ger chaque auteur ainsi que la FSF, nous affirmons +solennellement que le programme concern� ne fait l'objet d'aucune garantie. +Si un tiers le modifie puis le redistribue, tous ceux qui en recevront une +copie doivent savoir qu'il ne s'agit pas de l'original afin qu'une copie +d�fectueuse n'entache pas la r�putation de l'auteur du logiciel. + +Enfin, tout programme libre est sans cesse menac� par des d�p�ts de +brevets. Nous souhaitons � tout prix �viter que des distributeurs puissent +d�poser des brevets sur les Logiciels Libres pour leur propre compte. Pour +�viter cela, nous stipulons bien que tout d�p�t �ventuel de brevet doit +accorder express�ment � tout un chacun le libre usage du produit. + +Les dispositions pr�cises et les conditions de copie, de distribution et de +modification de nos logiciels sont les suivantes : + + Stipulations et conditions relatives � la copie, la distribution et la modification + + + _Article 0. + La pr�sente Licence s'applique � tout Programme (ou autre travail) o� + figure une note, plac�e par le d�tenteur des droits, stipulant que ledit + Programme ou travail peut �tre distribu� selon les termes de la pr�sente + Licence. Le terme Programme d�signe aussi bien le Programme + lui-m�me que tout travail qui en est d�riv� selon la loi, c'est-�-dire + tout ouvrage reproduisant le Programme ou une partie de celui-ci, � + l'identique ou bien modifi�, et/ou traduit dans une autre langue (la + traduction est consid�r�e comme une modification). Chaque personne + concern�e par la Licence Publique G�n�rale sera d�sign�e par le terme + Vous. + + Les activit�s autres que copie, distribution et modification ne sont pas + couvertes par la pr�sente Licence et sortent de son cadre. Rien ne + restreint l'utilisation du Programme et les donn�es issues de celui-ci ne + sont couvertes que si leur contenu constitue un travail bas� sur le + logiciel (ind�pendemment du fait d'avoir �t� r�alis� en lan�ant le + Programme). Tout d�pend de ce que le Programme est cens� produire. + + _Article 1. + Vous pouvez copier et distribuer des copies conformes du code source du + Programme, tel que Vous l'avez re�u, sur n'importe quel support, � + condition de placer sur chaque copie un copyright appropri� et une + restriction de garantie, de ne pas modifier ou omettre toutes les + stipulations se r�f�rant � la pr�sente Licence et � la limitation de + garantie, et de fournir avec toute copie du Programme un exemplaire de la + Licence. + + Vous pouvez demander une r�tribution financi�re pour la r�alisation de la + copie et demeurez libre de proposer une garantie assur�e par vos soins, + moyennant finances. + + _Article 2. + Vous pouvez modifier votre copie ou vos copies du Programme ou partie de + celui-ci, ou d'un travail bas� sur ce Programme, et copier et distribuer + ces modifications selon les termes de l'article 1, � condition de Vous + conformer �galement aux conditions suivantes : + + + a) Ajouter aux fichiers modifi�s l'indication tr�s claire des + modifications effectu�es, ainsi que la date de chaque changement. + + b) Distribuer sous les termes de la Licence Publique G�n�rale + l'ensemble de toute r�alisation contenant tout ou partie du + Programme, avec ou sans modifications. + c) Si le Programme modifi� lit des commandes de mani�re interactive + lors de son ex�cution, faire en sorte qu'il affiche, lors d'une + invocation ordinaire, le copyright appropri� en indiquant + clairement la limitation de garantie (ou la garantie que Vous Vous + engagez � fournir Vous-m�me), qu'il stipule que tout utilisateur + peut librement redistribuer le Programme selon les conditions de la + Licence Publique G�n�rale GNU, et qu'il montre � tout utilisateur + comment lire une copie de celle-ci (exception : si le + Programme original est interactif mais n'affiche pas un tel + message en temps normal, tout travail d�riv� de ce Programme ne + sera pas non plus contraint de l'afficher). + + Toutes ces conditions s'appliquent � l'ensemble des modifications. Si des + �l�ments identifiables de ce travail ne sont pas d�riv�s du Programme + et peuvent �tre raisonnablement consid�r�s comme ind�pendants, la + pr�sente Licence ne s'applique pas � ces �l�ments lorsque Vous les + distribuez seuls. + Mais, si Vous distribuez ces m�mes �l�ments comme partie d'un ensemble + coh�rent dont le reste est bas� sur un Programme soumis � la Licence, ils + lui sont �galement soumis, et la Licence s'�tend ainsi � l'ensemble du + produit, quel qu'en soit l'auteur. + + Cet article n'a pas pour but de s'approprier ou de contester vos + droits sur un travail enti�rement r�alis� par Vous, mais plut�t + d'ouvrir droit � un contr�le de la libre distribution de tout travail + d�riv� ou collectif bas� sur le Programme. + + En outre, toute fusion d'un autre travail, non bas� sur le Programme, + avec le Programme (ou avec un travail d�riv� de ce dernier), + effectu�e sur un support de stockage ou de distribution, ne fait pas + tomber cet autre travail sous le contr�le de la Licence. + + _Article 3. + Vous pouvez copier et distribuer le Programme (ou tout travail d�riv� + selon les conditions �nonc�es dans l'article 1) sous forme de code + objet ou ex�cutable, selon les termes des articles 0 et 1, � + condition de respecter les clauses suivantes : + + + a) Fournir le code source complet du Programme, + sous une forme lisible par un ordinateur et selon les termes des + articles 0 et 1, sur un support habituellement utilis� pour + l'�change de donn�es ou, + + b) Faire une offre �crite, valable pendant au moins trois ans, + pr�voyant de donner � tout tiers qui en fera la demande une copie, + sous forme lisible par un ordinateur, du code source correspondant, + pour un tarif n'exc�dant pas le co�t de la copie, selon + les termes des articles 0 et 1, sur un support couramment utilis� + pour l'�change de donn�es informatiques ou, + + c) Informer le destinataire de l'endroit o� le code source peut + �tre obtenu (cette solution n'est recevable que dans le cas d'une + distribution non commerciale, et uniquement si Vous avez re�u le + Programme sous forme de code objet ou ex�cutable avec l'offre + pr�vue � l'alin�a b ci-dessus). + + + Le code source d'un travail d�signe la forme de cet ouvrage sous laquelle + les modifications sont les plus ais�es. Sont ainsi d�sign�s la totalit� + du code source de tous les modules composant un Programme ex�cutable, de + m�me que tout fichier de d�finition associ�, ainsi que les scripts + utilis�s pour effectuer la compilation et l'installation du Programme + ex�cutable. Toutefois, l'environnement standard de d�veloppement du + syst�me d'exploitation mis en oeuvre (source ou binaire) -- compilateurs, + biblioth�ques, noyau, etc. -- constitue une exception, sauf si ces + �l�ments sont diffus�s en m�me temps que le Programme ex�cutable. + + Si la distribution de l'ex�cutable ou du code objet consiste � offrir un + acc�s permettant de copier le Programme depuis un endroit particulier, + l'offre d'un acc�s �quivalent pour se procurer le code source au m�me + endroit est consid�r� comme une distribution de ce code source, m�me si + l'utilisateur choisit de ne pas profiter de cette offre. + + _Article 4. + Vous ne pouvez pas copier, modifier, c�der, d�poser ou distribuer le + Programme d'une autre mani�re que l'autorise la Licence Publique G�n�rale. + Toute tentative de ce type annule imm�diatement vos droits d'utilisation du + Programme sous cette Licence. Toutefois, les tiers ayant re�u de Vous + des copies du Programme ou le droit d'utiliser ces copies continueront � + b�n�ficier de leur droit d'utilisation tant qu'ils respecteront pleinement + les conditions de la Licence. + + _Article 5. + Ne l'ayant pas sign�e, Vous n'�tes pas oblig� d'accepter cette + Licence. Cependant, rien d'autre ne Vous autorise � modifier ou distribuer + le Programme ou quelque travaux d�riv�s : la loi l'interdit tant que Vous + n'acceptez pas les termes de cette Licence. En cons�quence, en modifiant + ou en distribuant le Programme (ou tout travail bas� sur lui), Vous + acceptez implicitement tous les termes et conditions de cette Licence. + + _Article 6. + La diffusion d'un Programme (ou de tout travail d�riv�) suppose l'envoi + simultan� d'une licence autorisant la copie, la distribution ou la + modification du Programme, aux termes et conditions de la Licence. Vous + n'avez pas le droit d'imposer de restrictions suppl�mentaires aux droits + transmis au destinataire. Vous n'�tes pas responsable du respect de la + Licence par un tiers. + + _Article 7. + Si, � la suite d'une d�cision de Justice, d'une plainte en contrefa�on ou + pour toute autre raison (li�e ou non � la contrefa�on), des conditions Vous + sont impos�es (que ce soit par ordonnance, accord amiable ou autre) qui se + r�v�lent incompatibles avec les termes de la pr�sente Licence, Vous n'�tes + pas pour autant d�gag� des obligations li�es � celle-ci : si Vous ne + pouvez concilier vos obligations l�gales ou autres avec les conditions de + cette Licence, Vous ne devez pas distribuer le Programme. + + Si une partie quelconque de cet article est invalid�e ou inapplicable + pour quelque raison que ce soit, le reste de l'article continue de + s'appliquer et l'int�gralit� de l'article s'appliquera en toute autre + circonstance. + + Le pr�sent article n'a pas pour but de Vous pousser � enfreindre des + droits ou des dispositions l�gales ni en contester la validit� ; + son seul objectif est de prot�ger l'int�grit� du syst�me de + distribution du Logiciel Libre. De nombreuses personnes ont + g�n�reusement contribu� � la large gamme de Programmes distribu�e + de cette fa�on en toute confiance il appartient � chaque + auteur/donateur de d�cider de diffuser ses Programmes selon les crit�res + de son choix. + + _Article 8. + Si la distribution et/ou l'utilisation du Programme est limit�e dans + certains pays par des brevets ou des droits sur des interfaces, le + d�tenteur original des droits qui place le Programme sous la Licence + Publique G�n�rale peut ajouter explicitement une clause de limitation + g�ographique excluant ces pays. Dans ce cas, cette clause devient une + partie int�grante de la Licence. + + _Article 9. + La Free Software Foundation se r�serve le droit de publier p�riodiquement + des mises � jour ou de nouvelles versions de la Licence. R�dig�es dans le + m�me esprit que la pr�sente version, elles seront cependant susceptibles + d'en modifier certains d�tails � mesure que de nouveaux probl�mes se font + jour. + + Chaque version poss�de un num�ro distinct. Si le Programme pr�cise un + num�ro de version de cette Licence et � toute version ult�rieure �, Vous + avez le choix de suivre les termes et conditions de cette version ou de + toute autre version plus r�cente publi�e par la Free Software Foundation. + Si le Programme ne sp�cifie aucun num�ro de version, Vous pouvez alors + choisir l'une quelconque des versions publi�es par la Free Software + Foundation. + + + _Article 10. + Si Vous d�sirez incorporer des �l�ments du Programme dans d'autres + Programmes libres dont les conditions de distribution diff�rent, Vous devez + �crire � l'auteur pour lui en demander la permission. Pour ce qui est des + Programmes directement d�pos�s par la Free Software Foundation, + �crivez-nous : une exception est toujours envisageable. Notre d�cision + sera bas�e sur notre volont� de pr�server la libert� de notre Programme ou + de ses d�riv�s et celle de promouvoir le partage et la r�utilisation du + logiciel en g�n�ral. + + + LIMITATION DE GARANTIE + + + _Article 11. + + Parce que l'utilisation de ce Programme est libre et gratuite, aucune + garantie n'est fournie, comme le permet la loi. Sauf mention �crite, les + d�tenteurs du copyright et/ou les tiers fournissent le Programme en l'�tat, + sans aucune sorte de garantie explicite ou implicite, y compris les + garanties de commercialisation ou d'adaptation dans un but + particulier. Vous assumez tous les risques quant � la qualit� et aux effets + du Programme. Si le Programme est d�fectueux, Vous assumez le co�t de tous + les services, corrections ou r�parations n�cessaires. + + + _Article 12. + Sauf lorsqu'explicitement pr�vu par la Loi ou accept� par �crit, ni le + d�tenteur des droits, ni quiconque autoris� � modifier et/ou redistribuer + le Programme comme il est permis ci-dessus ne pourra �tre tenu pour + responsable de tout dommage direct, indirect, secondaire ou accessoire + (pertes financi�res dues au manque � gagner, � l'interruption d'activit�s + ou � la perte de donn�es, etc., d�coulant de l'utilisation du Programme ou + de l'impossibilit� d'utiliser celui-ci). + + + + FIN DES TERMES ET CONDITIONS + + Comment appliquer ces directives � vos nouveaux programmes + +Si vous d�veloppez un nouveau programme et d�sirez en faire b�n�ficier tout +un chacun, la meilleure m�thode est d'en faire un Logiciel Libre que tout +le monde pourra redistribuer et modifier selon les termes de la Licence +Publique G�n�rale. + +Pour cela, ins�rez les indications suivantes dans votre programme (il est +pr�f�rable et plus s�r de les faire figurer au d�but de chaque fichier +source dans tous les cas, chaque module source devra comporter au +minimum la ligne de � copyright � et indiquer o� r�sident toutes les +autres indications): + + +((une ligne pour donner le nom du programme et donner une id�e de +sa finalit�)) +Copyright (C) 19xx ((nom de l'auteur)) + +Ce programme est libre, vous pouvez le redistribuer et/ou le modifier +selon les termes de la Licence Publique G�n�rale GNU publi�e par la +Free Software Foundation (version 2 ou bien toute autre version +ult�rieure choisie par vous). + +Ce programme est distribu� car potentiellement utile, mais SANS AUCUNE +GARANTIE, ni explicite ni implicite, y compris les garanties de +commercialisation ou d'adaptation dans un but sp�cifique. +Reportez-vous � la Licence Publique G�n�rale GNU pour plus de d�tails. + +Vous devez avoir re�u une copie de la Licence Publique G�n�rale GNU +en m�me temps que ce programme si ce n'est pas le cas, �crivez � la +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307, �tats-Unis. + + +Ajoutez �galement votre adresse �lectronique, le cas �ch�ant, ainsi que +votre adresse postale. + +Si le programme est interactif, faites-lui afficher un court avertissement +du type de celui-ci � chaque invocation: + + +...(nom du programme) version 69, Copyright (C) 19aa nom de l'auteur + +...(nom du programme) est fourni sans AUCUNE GARANTIE. +Pour plus de d�tails, tapez `g'. + +Ce programme est libre et vous �tes encourag� � le redistribuer +sous certaines conditions tapez `c' pour plus de d�tails. + +Les commandes hypoth�tiques `g' et `c' doivent afficher les sections +appropri�es de la Licence Publique G�n�rale GNU. Bien entendu, vous pouvez +implanter ces commandes comme bon vous semble : options dans un menu, +ou bien accessibles d'un clic de souris, etc., tout d�pend de votre +programme. + +Si vous officiez en tant que programmeur, n'omettez pas de demander � votre +employeur, votre �tablissement scolaire ou autres de signer une d�charge +stipulant leur renoncement aux droits qu'ils pourraient avoir sur le +programme: +> +...((employeur, �cole...)) d�clare par la pr�sente ne pas revendiquer +de droits sur le programme � (nom du programme) � r�alis� par ...((nom de +l'auteur)). + +((signature du responsable)), ...((date)), +...((nom et qualit� du responsable)). + +La Licence Publique G�n�rale ne permet pas d'inclure votre programme dans +des logiciels sous licence commerciale sp�cifique. Si votre programme est +une fonction de biblioth�que, vous jugerez probablement plus judicieux de +le faire relever de la Licence G�n�rale de Biblioth�que GNU (LGPL) plut�t +que de la pr�sente. + ========================================================================== \ No newline at end of file diff --git a/htdocs/langs/fr_FR/html/gpl.txt b/htdocs/langs/fr_FR/html/gpl.txt index 63329a6aa748bff106c11f066ad8f1f381772be4..ed06504c98314dea9355204775f127fdfde81c2f 100644 --- a/htdocs/langs/fr_FR/html/gpl.txt +++ b/htdocs/langs/fr_FR/html/gpl.txt @@ -1,390 +1,390 @@ GNU GENERAL PUBLIC LICENSE - -Traduction de R.Cougnec et M.Makar�vitch - -Introduction : -This is an unofficial translation of the GNU General Public License into -French. It was not published by the Free Software Foundation, and does not -legally state the distribution terms for software that uses the GNU -GPL--only the original English text of the GNU GPL does that. However, we -hope that this translation will help French speakers understand the GNU GPL -better. - -Voici une adaptation non officielle de la Licence Publique G�n�rale du -projet GNU. Elle n'a pas �t� publi�e par la Free Software Foundation et son -contenu n'a aucune port�e l�gale car seule la version anglaise de ce -document d�taille le mode de distribution des logiciels sous GNU GPL. Nous -esp�rons cependant qu'elle permettra aux francophones de mieux comprendre -la GPL. - - -Licence Publique G�n�rale GNU Version 2, Juin 1991- - -Copyright (c) Free Software Foundation, Inc. -59 Temple Place, Suite 330, -Boston, MA 02111-1307 -�tats-Unis, 1989, 1991. -La copie et la distribution de copies exactes de ce document sont -autoris�es, mais aucune modification n'est permise. - - Pr�ambule - -Les licences d'utilisation de la plupart des programmes sont d�finies pour -limiter ou supprimer toute libert� � l'utilisateur. � l'inverse, la -Licence Publique G�n�rale (General Public License) est destin�e � vous -garantir la libert� de partager et de modifier les logiciels libres, et de -s'assurer que ces logiciels sont effectivement accessibles � tout -utilisateur. - -Cette Licence Publique G�n�rale s'applique � la plupart des programmes de -la Free Software Foundation, comme � tout autre programme dont l'auteur -l'aura d�cid� (d'autres logiciels de la FSF sont couverts pour leur part -par la Licence Publique G�n�rale pour Biblioth�ques GNU (LGPL)). Vous -pouvez aussi appliquer les termes de cette Licence � vos propres -programmes, si vous le d�sirez. - - _Libert� des logiciels ne signifie pas n�cessairement -gratuit�. Notre Licence est con�ue pour vous assurer la libert� de -distribuer des copies des programmes, gratuitement ou non, de recevoir le -code source ou de pouvoir l'obtenir, de modifier les programmes ou d'en -utiliser des �l�ments dans de nouveaux programmes libres, en sachant que -vous y �tes autoris�. - -Afin de garantir ces droits, nous avons d� introduire des restrictions -interdisant � quiconque de vous les refuser ou de vous demander d'y -renoncer. Ces restrictions vous imposent en retour certaines obligations si -vous distribuez ou modifiez des copies de programmes prot�g�s par la -Licence. En d'autre termes, il vous incombera en ce cas de : - - -transmettre aux destinataires tous les droits que vous poss�dez, - -exp�dier aux destinataires le code source ou bien tenir celui-ci � - leur disposition, - -leur remettre cette Licence afin qu'ils prennent connaissance de - leurs droits. - - -Nous prot�geons vos droits de deux fa�ons : d'abord par le copyright -du logiciel, ensuite par la remise de cette Licence qui vous autorise -l�galement � copier, distribuer et/ou modifier le logiciel. - -En outre, pour prot�ger chaque auteur ainsi que la FSF, nous affirmons -solennellement que le programme concern� ne fait l'objet d'aucune garantie. -Si un tiers le modifie puis le redistribue, tous ceux qui en recevront une -copie doivent savoir qu'il ne s'agit pas de l'original afin qu'une copie -d�fectueuse n'entache pas la r�putation de l'auteur du logiciel. - -Enfin, tout programme libre est sans cesse menac� par des d�p�ts de -brevets. Nous souhaitons � tout prix �viter que des distributeurs puissent -d�poser des brevets sur les Logiciels Libres pour leur propre compte. Pour -�viter cela, nous stipulons bien que tout d�p�t �ventuel de brevet doit -accorder express�ment � tout un chacun le libre usage du produit. - -Les dispositions pr�cises et les conditions de copie, de distribution et de -modification de nos logiciels sont les suivantes : - - Stipulations et conditions relatives � la copie, la distribution et la modification - - - _Article 0. - La pr�sente Licence s'applique � tout Programme (ou autre travail) o� - figure une note, plac�e par le d�tenteur des droits, stipulant que ledit - Programme ou travail peut �tre distribu� selon les termes de la pr�sente - Licence. Le terme Programme d�signe aussi bien le Programme - lui-m�me que tout travail qui en est d�riv� selon la loi, c'est-�-dire - tout ouvrage reproduisant le Programme ou une partie de celui-ci, � - l'identique ou bien modifi�, et/ou traduit dans une autre langue (la - traduction est consid�r�e comme une modification). Chaque personne - concern�e par la Licence Publique G�n�rale sera d�sign�e par le terme - Vous. - - Les activit�s autres que copie, distribution et modification ne sont pas - couvertes par la pr�sente Licence et sortent de son cadre. Rien ne - restreint l'utilisation du Programme et les donn�es issues de celui-ci ne - sont couvertes que si leur contenu constitue un travail bas� sur le - logiciel (ind�pendemment du fait d'avoir �t� r�alis� en lan�ant le - Programme). Tout d�pend de ce que le Programme est cens� produire. - - _Article 1. - Vous pouvez copier et distribuer des copies conformes du code source du - Programme, tel que Vous l'avez re�u, sur n'importe quel support, � - condition de placer sur chaque copie un copyright appropri� et une - restriction de garantie, de ne pas modifier ou omettre toutes les - stipulations se r�f�rant � la pr�sente Licence et � la limitation de - garantie, et de fournir avec toute copie du Programme un exemplaire de la - Licence. - - Vous pouvez demander une r�tribution financi�re pour la r�alisation de la - copie et demeurez libre de proposer une garantie assur�e par vos soins, - moyennant finances. - - _Article 2. - Vous pouvez modifier votre copie ou vos copies du Programme ou partie de - celui-ci, ou d'un travail bas� sur ce Programme, et copier et distribuer - ces modifications selon les termes de l'article 1, � condition de Vous - conformer �galement aux conditions suivantes : - - - a) Ajouter aux fichiers modifi�s l'indication tr�s claire des - modifications effectu�es, ainsi que la date de chaque changement. - - b) Distribuer sous les termes de la Licence Publique G�n�rale - l'ensemble de toute r�alisation contenant tout ou partie du - Programme, avec ou sans modifications. - c) Si le Programme modifi� lit des commandes de mani�re interactive - lors de son ex�cution, faire en sorte qu'il affiche, lors d'une - invocation ordinaire, le copyright appropri� en indiquant - clairement la limitation de garantie (ou la garantie que Vous Vous - engagez � fournir Vous-m�me), qu'il stipule que tout utilisateur - peut librement redistribuer le Programme selon les conditions de la - Licence Publique G�n�rale GNU, et qu'il montre � tout utilisateur - comment lire une copie de celle-ci (exception : si le - Programme original est interactif mais n'affiche pas un tel - message en temps normal, tout travail d�riv� de ce Programme ne - sera pas non plus contraint de l'afficher). - - Toutes ces conditions s'appliquent � l'ensemble des modifications. Si des - �l�ments identifiables de ce travail ne sont pas d�riv�s du Programme - et peuvent �tre raisonnablement consid�r�s comme ind�pendants, la - pr�sente Licence ne s'applique pas � ces �l�ments lorsque Vous les - distribuez seuls. - Mais, si Vous distribuez ces m�mes �l�ments comme partie d'un ensemble - coh�rent dont le reste est bas� sur un Programme soumis � la Licence, ils - lui sont �galement soumis, et la Licence s'�tend ainsi � l'ensemble du - produit, quel qu'en soit l'auteur. - - Cet article n'a pas pour but de s'approprier ou de contester vos - droits sur un travail enti�rement r�alis� par Vous, mais plut�t - d'ouvrir droit � un contr�le de la libre distribution de tout travail - d�riv� ou collectif bas� sur le Programme. - - En outre, toute fusion d'un autre travail, non bas� sur le Programme, - avec le Programme (ou avec un travail d�riv� de ce dernier), - effectu�e sur un support de stockage ou de distribution, ne fait pas - tomber cet autre travail sous le contr�le de la Licence. - - _Article 3. - Vous pouvez copier et distribuer le Programme (ou tout travail d�riv� - selon les conditions �nonc�es dans l'article 1) sous forme de code - objet ou ex�cutable, selon les termes des articles 0 et 1, � - condition de respecter les clauses suivantes : - - - a) Fournir le code source complet du Programme, - sous une forme lisible par un ordinateur et selon les termes des - articles 0 et 1, sur un support habituellement utilis� pour - l'�change de donn�es ou, - - b) Faire une offre �crite, valable pendant au moins trois ans, - pr�voyant de donner � tout tiers qui en fera la demande une copie, - sous forme lisible par un ordinateur, du code source correspondant, - pour un tarif n'exc�dant pas le co�t de la copie, selon - les termes des articles 0 et 1, sur un support couramment utilis� - pour l'�change de donn�es informatiques ou, - - c) Informer le destinataire de l'endroit o� le code source peut - �tre obtenu (cette solution n'est recevable que dans le cas d'une - distribution non commerciale, et uniquement si Vous avez re�u le - Programme sous forme de code objet ou ex�cutable avec l'offre - pr�vue � l'alin�a b ci-dessus). - - - Le code source d'un travail d�signe la forme de cet ouvrage sous laquelle - les modifications sont les plus ais�es. Sont ainsi d�sign�s la totalit� - du code source de tous les modules composant un Programme ex�cutable, de - m�me que tout fichier de d�finition associ�, ainsi que les scripts - utilis�s pour effectuer la compilation et l'installation du Programme - ex�cutable. Toutefois, l'environnement standard de d�veloppement du - syst�me d'exploitation mis en oeuvre (source ou binaire) -- compilateurs, - biblioth�ques, noyau, etc. -- constitue une exception, sauf si ces - �l�ments sont diffus�s en m�me temps que le Programme ex�cutable. - - Si la distribution de l'ex�cutable ou du code objet consiste � offrir un - acc�s permettant de copier le Programme depuis un endroit particulier, - l'offre d'un acc�s �quivalent pour se procurer le code source au m�me - endroit est consid�r� comme une distribution de ce code source, m�me si - l'utilisateur choisit de ne pas profiter de cette offre. - - _Article 4. - Vous ne pouvez pas copier, modifier, c�der, d�poser ou distribuer le - Programme d'une autre mani�re que l'autorise la Licence Publique G�n�rale. - Toute tentative de ce type annule imm�diatement vos droits d'utilisation du - Programme sous cette Licence. Toutefois, les tiers ayant re�u de Vous - des copies du Programme ou le droit d'utiliser ces copies continueront � - b�n�ficier de leur droit d'utilisation tant qu'ils respecteront pleinement - les conditions de la Licence. - - _Article 5. - Ne l'ayant pas sign�e, Vous n'�tes pas oblig� d'accepter cette - Licence. Cependant, rien d'autre ne Vous autorise � modifier ou distribuer - le Programme ou quelque travaux d�riv�s : la loi l'interdit tant que Vous - n'acceptez pas les termes de cette Licence. En cons�quence, en modifiant - ou en distribuant le Programme (ou tout travail bas� sur lui), Vous - acceptez implicitement tous les termes et conditions de cette Licence. - - _Article 6. - La diffusion d'un Programme (ou de tout travail d�riv�) suppose l'envoi - simultan� d'une licence autorisant la copie, la distribution ou la - modification du Programme, aux termes et conditions de la Licence. Vous - n'avez pas le droit d'imposer de restrictions suppl�mentaires aux droits - transmis au destinataire. Vous n'�tes pas responsable du respect de la - Licence par un tiers. - - _Article 7. - Si, � la suite d'une d�cision de Justice, d'une plainte en contrefa�on ou - pour toute autre raison (li�e ou non � la contrefa�on), des conditions Vous - sont impos�es (que ce soit par ordonnance, accord amiable ou autre) qui se - r�v�lent incompatibles avec les termes de la pr�sente Licence, Vous n'�tes - pas pour autant d�gag� des obligations li�es � celle-ci : si Vous ne - pouvez concilier vos obligations l�gales ou autres avec les conditions de - cette Licence, Vous ne devez pas distribuer le Programme. - - Si une partie quelconque de cet article est invalid�e ou inapplicable - pour quelque raison que ce soit, le reste de l'article continue de - s'appliquer et l'int�gralit� de l'article s'appliquera en toute autre - circonstance. - - Le pr�sent article n'a pas pour but de Vous pousser � enfreindre des - droits ou des dispositions l�gales ni en contester la validit� ; - son seul objectif est de prot�ger l'int�grit� du syst�me de - distribution du Logiciel Libre. De nombreuses personnes ont - g�n�reusement contribu� � la large gamme de Programmes distribu�e - de cette fa�on en toute confiance il appartient � chaque - auteur/donateur de d�cider de diffuser ses Programmes selon les crit�res - de son choix. - - _Article 8. - Si la distribution et/ou l'utilisation du Programme est limit�e dans - certains pays par des brevets ou des droits sur des interfaces, le - d�tenteur original des droits qui place le Programme sous la Licence - Publique G�n�rale peut ajouter explicitement une clause de limitation - g�ographique excluant ces pays. Dans ce cas, cette clause devient une - partie int�grante de la Licence. - - _Article 9. - La Free Software Foundation se r�serve le droit de publier p�riodiquement - des mises � jour ou de nouvelles versions de la Licence. R�dig�es dans le - m�me esprit que la pr�sente version, elles seront cependant susceptibles - d'en modifier certains d�tails � mesure que de nouveaux probl�mes se font - jour. - - Chaque version poss�de un num�ro distinct. Si le Programme pr�cise un - num�ro de version de cette Licence et � toute version ult�rieure �, Vous - avez le choix de suivre les termes et conditions de cette version ou de - toute autre version plus r�cente publi�e par la Free Software Foundation. - Si le Programme ne sp�cifie aucun num�ro de version, Vous pouvez alors - choisir l'une quelconque des versions publi�es par la Free Software - Foundation. - - - _Article 10. - Si Vous d�sirez incorporer des �l�ments du Programme dans d'autres - Programmes libres dont les conditions de distribution diff�rent, Vous devez - �crire � l'auteur pour lui en demander la permission. Pour ce qui est des - Programmes directement d�pos�s par la Free Software Foundation, - �crivez-nous : une exception est toujours envisageable. Notre d�cision - sera bas�e sur notre volont� de pr�server la libert� de notre Programme ou - de ses d�riv�s et celle de promouvoir le partage et la r�utilisation du - logiciel en g�n�ral. - - - LIMITATION DE GARANTIE - - - _Article 11. - - Parce que l'utilisation de ce Programme est libre et gratuite, aucune - garantie n'est fournie, comme le permet la loi. Sauf mention �crite, les - d�tenteurs du copyright et/ou les tiers fournissent le Programme en l'�tat, - sans aucune sorte de garantie explicite ou implicite, y compris les - garanties de commercialisation ou d'adaptation dans un but - particulier. Vous assumez tous les risques quant � la qualit� et aux effets - du Programme. Si le Programme est d�fectueux, Vous assumez le co�t de tous - les services, corrections ou r�parations n�cessaires. - - - _Article 12. - Sauf lorsqu'explicitement pr�vu par la Loi ou accept� par �crit, ni le - d�tenteur des droits, ni quiconque autoris� � modifier et/ou redistribuer - le Programme comme il est permis ci-dessus ne pourra �tre tenu pour - responsable de tout dommage direct, indirect, secondaire ou accessoire - (pertes financi�res dues au manque � gagner, � l'interruption d'activit�s - ou � la perte de donn�es, etc., d�coulant de l'utilisation du Programme ou - de l'impossibilit� d'utiliser celui-ci). - - - - FIN DES TERMES ET CONDITIONS - - Comment appliquer ces directives � vos nouveaux programmes - -Si vous d�veloppez un nouveau programme et d�sirez en faire b�n�ficier tout -un chacun, la meilleure m�thode est d'en faire un Logiciel Libre que tout -le monde pourra redistribuer et modifier selon les termes de la Licence -Publique G�n�rale. - -Pour cela, ins�rez les indications suivantes dans votre programme (il est -pr�f�rable et plus s�r de les faire figurer au d�but de chaque fichier -source dans tous les cas, chaque module source devra comporter au -minimum la ligne de � copyright � et indiquer o� r�sident toutes les -autres indications): - - -((une ligne pour donner le nom du programme et donner une id�e de -sa finalit�)) -Copyright (C) 19xx ((nom de l'auteur)) - -Ce programme est libre, vous pouvez le redistribuer et/ou le modifier -selon les termes de la Licence Publique G�n�rale GNU publi�e par la -Free Software Foundation (version 2 ou bien toute autre version -ult�rieure choisie par vous). - -Ce programme est distribu� car potentiellement utile, mais SANS AUCUNE -GARANTIE, ni explicite ni implicite, y compris les garanties de -commercialisation ou d'adaptation dans un but sp�cifique. -Reportez-vous � la Licence Publique G�n�rale GNU pour plus de d�tails. - -Vous devez avoir re�u une copie de la Licence Publique G�n�rale GNU -en m�me temps que ce programme si ce n'est pas le cas, �crivez � la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, �tats-Unis. - - -Ajoutez �galement votre adresse �lectronique, le cas �ch�ant, ainsi que -votre adresse postale. - -Si le programme est interactif, faites-lui afficher un court avertissement -du type de celui-ci � chaque invocation: - - -...(nom du programme) version 69, Copyright (C) 19aa nom de l'auteur - -...(nom du programme) est fourni sans AUCUNE GARANTIE. -Pour plus de d�tails, tapez `g'. - -Ce programme est libre et vous �tes encourag� � le redistribuer -sous certaines conditions tapez `c' pour plus de d�tails. - -Les commandes hypoth�tiques `g' et `c' doivent afficher les sections -appropri�es de la Licence Publique G�n�rale GNU. Bien entendu, vous pouvez -implanter ces commandes comme bon vous semble : options dans un menu, -ou bien accessibles d'un clic de souris, etc., tout d�pend de votre -programme. - -Si vous officiez en tant que programmeur, n'omettez pas de demander � votre -employeur, votre �tablissement scolaire ou autres de signer une d�charge -stipulant leur renoncement aux droits qu'ils pourraient avoir sur le -programme: -> -...((employeur, �cole...)) d�clare par la pr�sente ne pas revendiquer -de droits sur le programme � (nom du programme) � r�alis� par ...((nom de -l'auteur)). - -((signature du responsable)), ...((date)), -...((nom et qualit� du responsable)). - -La Licence Publique G�n�rale ne permet pas d'inclure votre programme dans -des logiciels sous licence commerciale sp�cifique. Si votre programme est -une fonction de biblioth�que, vous jugerez probablement plus judicieux de -le faire relever de la Licence G�n�rale de Biblioth�que GNU (LGPL) plut�t -que de la pr�sente. - + +Traduction de R.Cougnec et M.Makar�vitch + +Introduction : +This is an unofficial translation of the GNU General Public License into +French. It was not published by the Free Software Foundation, and does not +legally state the distribution terms for software that uses the GNU +GPL--only the original English text of the GNU GPL does that. However, we +hope that this translation will help French speakers understand the GNU GPL +better. + +Voici une adaptation non officielle de la Licence Publique G�n�rale du +projet GNU. Elle n'a pas �t� publi�e par la Free Software Foundation et son +contenu n'a aucune port�e l�gale car seule la version anglaise de ce +document d�taille le mode de distribution des logiciels sous GNU GPL. Nous +esp�rons cependant qu'elle permettra aux francophones de mieux comprendre +la GPL. + + -Licence Publique G�n�rale GNU Version 2, Juin 1991- + +Copyright (c) Free Software Foundation, Inc. +59 Temple Place, Suite 330, +Boston, MA 02111-1307 +�tats-Unis, 1989, 1991. +La copie et la distribution de copies exactes de ce document sont +autoris�es, mais aucune modification n'est permise. + + Pr�ambule + +Les licences d'utilisation de la plupart des programmes sont d�finies pour +limiter ou supprimer toute libert� � l'utilisateur. � l'inverse, la +Licence Publique G�n�rale (General Public License) est destin�e � vous +garantir la libert� de partager et de modifier les logiciels libres, et de +s'assurer que ces logiciels sont effectivement accessibles � tout +utilisateur. + +Cette Licence Publique G�n�rale s'applique � la plupart des programmes de +la Free Software Foundation, comme � tout autre programme dont l'auteur +l'aura d�cid� (d'autres logiciels de la FSF sont couverts pour leur part +par la Licence Publique G�n�rale pour Biblioth�ques GNU (LGPL)). Vous +pouvez aussi appliquer les termes de cette Licence � vos propres +programmes, si vous le d�sirez. + + _Libert� des logiciels ne signifie pas n�cessairement +gratuit�. Notre Licence est con�ue pour vous assurer la libert� de +distribuer des copies des programmes, gratuitement ou non, de recevoir le +code source ou de pouvoir l'obtenir, de modifier les programmes ou d'en +utiliser des �l�ments dans de nouveaux programmes libres, en sachant que +vous y �tes autoris�. + +Afin de garantir ces droits, nous avons d� introduire des restrictions +interdisant � quiconque de vous les refuser ou de vous demander d'y +renoncer. Ces restrictions vous imposent en retour certaines obligations si +vous distribuez ou modifiez des copies de programmes prot�g�s par la +Licence. En d'autre termes, il vous incombera en ce cas de : + + -transmettre aux destinataires tous les droits que vous poss�dez, + -exp�dier aux destinataires le code source ou bien tenir celui-ci � + leur disposition, + -leur remettre cette Licence afin qu'ils prennent connaissance de + leurs droits. + + +Nous prot�geons vos droits de deux fa�ons : d'abord par le copyright +du logiciel, ensuite par la remise de cette Licence qui vous autorise +l�galement � copier, distribuer et/ou modifier le logiciel. + +En outre, pour prot�ger chaque auteur ainsi que la FSF, nous affirmons +solennellement que le programme concern� ne fait l'objet d'aucune garantie. +Si un tiers le modifie puis le redistribue, tous ceux qui en recevront une +copie doivent savoir qu'il ne s'agit pas de l'original afin qu'une copie +d�fectueuse n'entache pas la r�putation de l'auteur du logiciel. + +Enfin, tout programme libre est sans cesse menac� par des d�p�ts de +brevets. Nous souhaitons � tout prix �viter que des distributeurs puissent +d�poser des brevets sur les Logiciels Libres pour leur propre compte. Pour +�viter cela, nous stipulons bien que tout d�p�t �ventuel de brevet doit +accorder express�ment � tout un chacun le libre usage du produit. + +Les dispositions pr�cises et les conditions de copie, de distribution et de +modification de nos logiciels sont les suivantes : + + Stipulations et conditions relatives � la copie, la distribution et la modification + + + _Article 0. + La pr�sente Licence s'applique � tout Programme (ou autre travail) o� + figure une note, plac�e par le d�tenteur des droits, stipulant que ledit + Programme ou travail peut �tre distribu� selon les termes de la pr�sente + Licence. Le terme Programme d�signe aussi bien le Programme + lui-m�me que tout travail qui en est d�riv� selon la loi, c'est-�-dire + tout ouvrage reproduisant le Programme ou une partie de celui-ci, � + l'identique ou bien modifi�, et/ou traduit dans une autre langue (la + traduction est consid�r�e comme une modification). Chaque personne + concern�e par la Licence Publique G�n�rale sera d�sign�e par le terme + Vous. + + Les activit�s autres que copie, distribution et modification ne sont pas + couvertes par la pr�sente Licence et sortent de son cadre. Rien ne + restreint l'utilisation du Programme et les donn�es issues de celui-ci ne + sont couvertes que si leur contenu constitue un travail bas� sur le + logiciel (ind�pendemment du fait d'avoir �t� r�alis� en lan�ant le + Programme). Tout d�pend de ce que le Programme est cens� produire. + + _Article 1. + Vous pouvez copier et distribuer des copies conformes du code source du + Programme, tel que Vous l'avez re�u, sur n'importe quel support, � + condition de placer sur chaque copie un copyright appropri� et une + restriction de garantie, de ne pas modifier ou omettre toutes les + stipulations se r�f�rant � la pr�sente Licence et � la limitation de + garantie, et de fournir avec toute copie du Programme un exemplaire de la + Licence. + + Vous pouvez demander une r�tribution financi�re pour la r�alisation de la + copie et demeurez libre de proposer une garantie assur�e par vos soins, + moyennant finances. + + _Article 2. + Vous pouvez modifier votre copie ou vos copies du Programme ou partie de + celui-ci, ou d'un travail bas� sur ce Programme, et copier et distribuer + ces modifications selon les termes de l'article 1, � condition de Vous + conformer �galement aux conditions suivantes : + + + a) Ajouter aux fichiers modifi�s l'indication tr�s claire des + modifications effectu�es, ainsi que la date de chaque changement. + + b) Distribuer sous les termes de la Licence Publique G�n�rale + l'ensemble de toute r�alisation contenant tout ou partie du + Programme, avec ou sans modifications. + c) Si le Programme modifi� lit des commandes de mani�re interactive + lors de son ex�cution, faire en sorte qu'il affiche, lors d'une + invocation ordinaire, le copyright appropri� en indiquant + clairement la limitation de garantie (ou la garantie que Vous Vous + engagez � fournir Vous-m�me), qu'il stipule que tout utilisateur + peut librement redistribuer le Programme selon les conditions de la + Licence Publique G�n�rale GNU, et qu'il montre � tout utilisateur + comment lire une copie de celle-ci (exception : si le + Programme original est interactif mais n'affiche pas un tel + message en temps normal, tout travail d�riv� de ce Programme ne + sera pas non plus contraint de l'afficher). + + Toutes ces conditions s'appliquent � l'ensemble des modifications. Si des + �l�ments identifiables de ce travail ne sont pas d�riv�s du Programme + et peuvent �tre raisonnablement consid�r�s comme ind�pendants, la + pr�sente Licence ne s'applique pas � ces �l�ments lorsque Vous les + distribuez seuls. + Mais, si Vous distribuez ces m�mes �l�ments comme partie d'un ensemble + coh�rent dont le reste est bas� sur un Programme soumis � la Licence, ils + lui sont �galement soumis, et la Licence s'�tend ainsi � l'ensemble du + produit, quel qu'en soit l'auteur. + + Cet article n'a pas pour but de s'approprier ou de contester vos + droits sur un travail enti�rement r�alis� par Vous, mais plut�t + d'ouvrir droit � un contr�le de la libre distribution de tout travail + d�riv� ou collectif bas� sur le Programme. + + En outre, toute fusion d'un autre travail, non bas� sur le Programme, + avec le Programme (ou avec un travail d�riv� de ce dernier), + effectu�e sur un support de stockage ou de distribution, ne fait pas + tomber cet autre travail sous le contr�le de la Licence. + + _Article 3. + Vous pouvez copier et distribuer le Programme (ou tout travail d�riv� + selon les conditions �nonc�es dans l'article 1) sous forme de code + objet ou ex�cutable, selon les termes des articles 0 et 1, � + condition de respecter les clauses suivantes : + + + a) Fournir le code source complet du Programme, + sous une forme lisible par un ordinateur et selon les termes des + articles 0 et 1, sur un support habituellement utilis� pour + l'�change de donn�es ou, + + b) Faire une offre �crite, valable pendant au moins trois ans, + pr�voyant de donner � tout tiers qui en fera la demande une copie, + sous forme lisible par un ordinateur, du code source correspondant, + pour un tarif n'exc�dant pas le co�t de la copie, selon + les termes des articles 0 et 1, sur un support couramment utilis� + pour l'�change de donn�es informatiques ou, + + c) Informer le destinataire de l'endroit o� le code source peut + �tre obtenu (cette solution n'est recevable que dans le cas d'une + distribution non commerciale, et uniquement si Vous avez re�u le + Programme sous forme de code objet ou ex�cutable avec l'offre + pr�vue � l'alin�a b ci-dessus). + + + Le code source d'un travail d�signe la forme de cet ouvrage sous laquelle + les modifications sont les plus ais�es. Sont ainsi d�sign�s la totalit� + du code source de tous les modules composant un Programme ex�cutable, de + m�me que tout fichier de d�finition associ�, ainsi que les scripts + utilis�s pour effectuer la compilation et l'installation du Programme + ex�cutable. Toutefois, l'environnement standard de d�veloppement du + syst�me d'exploitation mis en oeuvre (source ou binaire) -- compilateurs, + biblioth�ques, noyau, etc. -- constitue une exception, sauf si ces + �l�ments sont diffus�s en m�me temps que le Programme ex�cutable. + + Si la distribution de l'ex�cutable ou du code objet consiste � offrir un + acc�s permettant de copier le Programme depuis un endroit particulier, + l'offre d'un acc�s �quivalent pour se procurer le code source au m�me + endroit est consid�r� comme une distribution de ce code source, m�me si + l'utilisateur choisit de ne pas profiter de cette offre. + + _Article 4. + Vous ne pouvez pas copier, modifier, c�der, d�poser ou distribuer le + Programme d'une autre mani�re que l'autorise la Licence Publique G�n�rale. + Toute tentative de ce type annule imm�diatement vos droits d'utilisation du + Programme sous cette Licence. Toutefois, les tiers ayant re�u de Vous + des copies du Programme ou le droit d'utiliser ces copies continueront � + b�n�ficier de leur droit d'utilisation tant qu'ils respecteront pleinement + les conditions de la Licence. + + _Article 5. + Ne l'ayant pas sign�e, Vous n'�tes pas oblig� d'accepter cette + Licence. Cependant, rien d'autre ne Vous autorise � modifier ou distribuer + le Programme ou quelque travaux d�riv�s : la loi l'interdit tant que Vous + n'acceptez pas les termes de cette Licence. En cons�quence, en modifiant + ou en distribuant le Programme (ou tout travail bas� sur lui), Vous + acceptez implicitement tous les termes et conditions de cette Licence. + + _Article 6. + La diffusion d'un Programme (ou de tout travail d�riv�) suppose l'envoi + simultan� d'une licence autorisant la copie, la distribution ou la + modification du Programme, aux termes et conditions de la Licence. Vous + n'avez pas le droit d'imposer de restrictions suppl�mentaires aux droits + transmis au destinataire. Vous n'�tes pas responsable du respect de la + Licence par un tiers. + + _Article 7. + Si, � la suite d'une d�cision de Justice, d'une plainte en contrefa�on ou + pour toute autre raison (li�e ou non � la contrefa�on), des conditions Vous + sont impos�es (que ce soit par ordonnance, accord amiable ou autre) qui se + r�v�lent incompatibles avec les termes de la pr�sente Licence, Vous n'�tes + pas pour autant d�gag� des obligations li�es � celle-ci : si Vous ne + pouvez concilier vos obligations l�gales ou autres avec les conditions de + cette Licence, Vous ne devez pas distribuer le Programme. + + Si une partie quelconque de cet article est invalid�e ou inapplicable + pour quelque raison que ce soit, le reste de l'article continue de + s'appliquer et l'int�gralit� de l'article s'appliquera en toute autre + circonstance. + + Le pr�sent article n'a pas pour but de Vous pousser � enfreindre des + droits ou des dispositions l�gales ni en contester la validit� ; + son seul objectif est de prot�ger l'int�grit� du syst�me de + distribution du Logiciel Libre. De nombreuses personnes ont + g�n�reusement contribu� � la large gamme de Programmes distribu�e + de cette fa�on en toute confiance il appartient � chaque + auteur/donateur de d�cider de diffuser ses Programmes selon les crit�res + de son choix. + + _Article 8. + Si la distribution et/ou l'utilisation du Programme est limit�e dans + certains pays par des brevets ou des droits sur des interfaces, le + d�tenteur original des droits qui place le Programme sous la Licence + Publique G�n�rale peut ajouter explicitement une clause de limitation + g�ographique excluant ces pays. Dans ce cas, cette clause devient une + partie int�grante de la Licence. + + _Article 9. + La Free Software Foundation se r�serve le droit de publier p�riodiquement + des mises � jour ou de nouvelles versions de la Licence. R�dig�es dans le + m�me esprit que la pr�sente version, elles seront cependant susceptibles + d'en modifier certains d�tails � mesure que de nouveaux probl�mes se font + jour. + + Chaque version poss�de un num�ro distinct. Si le Programme pr�cise un + num�ro de version de cette Licence et � toute version ult�rieure �, Vous + avez le choix de suivre les termes et conditions de cette version ou de + toute autre version plus r�cente publi�e par la Free Software Foundation. + Si le Programme ne sp�cifie aucun num�ro de version, Vous pouvez alors + choisir l'une quelconque des versions publi�es par la Free Software + Foundation. + + + _Article 10. + Si Vous d�sirez incorporer des �l�ments du Programme dans d'autres + Programmes libres dont les conditions de distribution diff�rent, Vous devez + �crire � l'auteur pour lui en demander la permission. Pour ce qui est des + Programmes directement d�pos�s par la Free Software Foundation, + �crivez-nous : une exception est toujours envisageable. Notre d�cision + sera bas�e sur notre volont� de pr�server la libert� de notre Programme ou + de ses d�riv�s et celle de promouvoir le partage et la r�utilisation du + logiciel en g�n�ral. + + + LIMITATION DE GARANTIE + + + _Article 11. + + Parce que l'utilisation de ce Programme est libre et gratuite, aucune + garantie n'est fournie, comme le permet la loi. Sauf mention �crite, les + d�tenteurs du copyright et/ou les tiers fournissent le Programme en l'�tat, + sans aucune sorte de garantie explicite ou implicite, y compris les + garanties de commercialisation ou d'adaptation dans un but + particulier. Vous assumez tous les risques quant � la qualit� et aux effets + du Programme. Si le Programme est d�fectueux, Vous assumez le co�t de tous + les services, corrections ou r�parations n�cessaires. + + + _Article 12. + Sauf lorsqu'explicitement pr�vu par la Loi ou accept� par �crit, ni le + d�tenteur des droits, ni quiconque autoris� � modifier et/ou redistribuer + le Programme comme il est permis ci-dessus ne pourra �tre tenu pour + responsable de tout dommage direct, indirect, secondaire ou accessoire + (pertes financi�res dues au manque � gagner, � l'interruption d'activit�s + ou � la perte de donn�es, etc., d�coulant de l'utilisation du Programme ou + de l'impossibilit� d'utiliser celui-ci). + + + + FIN DES TERMES ET CONDITIONS + + Comment appliquer ces directives � vos nouveaux programmes + +Si vous d�veloppez un nouveau programme et d�sirez en faire b�n�ficier tout +un chacun, la meilleure m�thode est d'en faire un Logiciel Libre que tout +le monde pourra redistribuer et modifier selon les termes de la Licence +Publique G�n�rale. + +Pour cela, ins�rez les indications suivantes dans votre programme (il est +pr�f�rable et plus s�r de les faire figurer au d�but de chaque fichier +source dans tous les cas, chaque module source devra comporter au +minimum la ligne de � copyright � et indiquer o� r�sident toutes les +autres indications): + + +((une ligne pour donner le nom du programme et donner une id�e de +sa finalit�)) +Copyright (C) 19xx ((nom de l'auteur)) + +Ce programme est libre, vous pouvez le redistribuer et/ou le modifier +selon les termes de la Licence Publique G�n�rale GNU publi�e par la +Free Software Foundation (version 2 ou bien toute autre version +ult�rieure choisie par vous). + +Ce programme est distribu� car potentiellement utile, mais SANS AUCUNE +GARANTIE, ni explicite ni implicite, y compris les garanties de +commercialisation ou d'adaptation dans un but sp�cifique. +Reportez-vous � la Licence Publique G�n�rale GNU pour plus de d�tails. + +Vous devez avoir re�u une copie de la Licence Publique G�n�rale GNU +en m�me temps que ce programme si ce n'est pas le cas, �crivez � la +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307, �tats-Unis. + + +Ajoutez �galement votre adresse �lectronique, le cas �ch�ant, ainsi que +votre adresse postale. + +Si le programme est interactif, faites-lui afficher un court avertissement +du type de celui-ci � chaque invocation: + + +...(nom du programme) version 69, Copyright (C) 19aa nom de l'auteur + +...(nom du programme) est fourni sans AUCUNE GARANTIE. +Pour plus de d�tails, tapez `g'. + +Ce programme est libre et vous �tes encourag� � le redistribuer +sous certaines conditions tapez `c' pour plus de d�tails. + +Les commandes hypoth�tiques `g' et `c' doivent afficher les sections +appropri�es de la Licence Publique G�n�rale GNU. Bien entendu, vous pouvez +implanter ces commandes comme bon vous semble : options dans un menu, +ou bien accessibles d'un clic de souris, etc., tout d�pend de votre +programme. + +Si vous officiez en tant que programmeur, n'omettez pas de demander � votre +employeur, votre �tablissement scolaire ou autres de signer une d�charge +stipulant leur renoncement aux droits qu'ils pourraient avoir sur le +programme: +> +...((employeur, �cole...)) d�clare par la pr�sente ne pas revendiquer +de droits sur le programme � (nom du programme) � r�alis� par ...((nom de +l'auteur)). + +((signature du responsable)), ...((date)), +...((nom et qualit� du responsable)). + +La Licence Publique G�n�rale ne permet pas d'inclure votre programme dans +des logiciels sous licence commerciale sp�cifique. Si votre programme est +une fonction de biblioth�que, vous jugerez probablement plus judicieux de +le faire relever de la Licence G�n�rale de Biblioth�que GNU (LGPL) plut�t +que de la pr�sente. + ========================================================================== \ No newline at end of file diff --git a/htdocs/langs/pt_PT/dict.lang b/htdocs/langs/pt_PT/dict.lang index 2d96850b5fc9eec0f98282dbb349754635f7c568..8e1ad5acb115ac5cfb2b01f1f97bd5095665b73c 100644 --- a/htdocs/langs/pt_PT/dict.lang +++ b/htdocs/langs/pt_PT/dict.lang @@ -1,25 +1,25 @@ -# Dolibarr language file - pt_PT - dict -CountryFR=Fran�a -CountryBE=Belgica -CountryIT=Italia -CountryES=Espanha -CountryDE=Alemanha -CountryCH=Sui�a -CountryGB=Gr�-Bretanha -CountryIE=Irlanda -CountryCN=China -CountryTN=Tun�sia -CountryUS=Estados Unidos -CountryMA=Marrocos -CountryDZ=Algeria -CountryCA=Canada -CountryTG=Togo -CountryGA=Gab�o -CountryNL=Holanda -CountryHU=Hungria -CountryRU=Russia -CountrySE=Su�cia -CountryCI=Costa do Marfim -CountrySN=Senegal -CountryAR=Argentina +# Dolibarr language file - pt_PT - dict +CountryFR=Fran�a +CountryBE=Belgica +CountryIT=Italia +CountryES=Espanha +CountryDE=Alemanha +CountryCH=Sui�a +CountryGB=Gr�-Bretanha +CountryIE=Irlanda +CountryCN=China +CountryTN=Tun�sia +CountryUS=Estados Unidos +CountryMA=Marrocos +CountryDZ=Algeria +CountryCA=Canada +CountryTG=Togo +CountryGA=Gab�o +CountryNL=Holanda +CountryHU=Hungria +CountryRU=Russia +CountrySE=Su�cia +CountryCI=Costa do Marfim +CountrySN=Senegal +CountryAR=Argentina CountryCM=Camar�es \ No newline at end of file diff --git a/htdocs/langs/pt_PT/html/gpl.txt b/htdocs/langs/pt_PT/html/gpl.txt index afdd894c1eca2fbf1519dc3e4ec917e879f73fb2..03d34611e3d45e722c3c84e373fd62e29d4a6b46 100644 --- a/htdocs/langs/pt_PT/html/gpl.txt +++ b/htdocs/langs/pt_PT/html/gpl.txt @@ -1,378 +1,378 @@ -LICEN�A P�BLICA GERAL GNU -Vers�o 2, junho de 1991 - - This is an unofficial translation of the GNU General Public License into - Portuguese. It was not published by the Free Software Foundation, and does not - legally state the distribution terms for software that uses the GNU GPL -- only - the original English text of the GNU GPL does that. However, we hope that this - translation will help Portuguese speakers understand the GNU GPL better. - - Esta � uma tradu��o n�o-oficial da Licen�a P�blica Geral GNU ("GPL GNU") para - Portugu�s. N�o foi publicada pela Free Software Foundation, e legalmente n�o - afirma os termos de distribui��o de software que utilize a GPL GNU -- apenas o - texto original da GPL GNU, em ingl�s, faz isso. Contudo, esperamos que esta - tradu��o ajude aos que falam portugu�s a entender melhor a GPL GNU. - -Para sugest�es ou correc��es a esta tradu��o, contacte: - -miguel.andrade@neoscopio.com - - ---- Tradu��o do documento original a partir desta linha --- - - -LICEN�A P�BLICA GERAL GNU -Vers�o 2, junho de 1991 - - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, - Cambridge, MA 02139, USA - - A qualquer pessoa � permitido copiar e distribuir c�pias deste documento de - licen�a, desde que sem qualquer altera��o. - -Introdu��o - - As licen�as de software s�o normalmente desenvolvidas para restringir a - liberdade de compartilh�-lo e modifica-lo. Pelo contr�rio, a Licen�a P�blica - Geral GNU pretende garantir a sua liberdade de compartilhar e modificar o - software livre -- garantindo que o software ser� livre para os seus - utilizadores. Esta Licen�a P�blica Geral aplica-se � maioria do software da - Free Software Foundation e a qualquer outro programa ao qual o seu autor decida - aplic�-la. (Algum software da FSF � cobertos pela Licen�a P�blica Geral de - Bibliotecas.) Tamb�m poder� aplic�-la aos seus programas. - - Quando nos referimos a software livre, estamo-nos a referir � liberdade e n�o - ao pre�o. A Licen�a P�blica Geral (GPL - General Public Licence - em Ingl�s.) - foi desenvolvida para garantir a sua liberdade de distribuir c�pias de software - livre (e cobrar por isso, se quiser); receber o c�digo-fonte ou ter acesso a - ele, se quiser; poder modificar o software ou utilizar partes dele em novos - programas livres; e que saiba que est� no seu direito de o fazer. - - Para proteger seus direitos, precisamos fazer restri��es que impe�am a qualquer - um negar estes direitos ou solicitar que voc� abdique deles. Estas restri��es - traduzem-se em certas responsabilidades para si, caso venha a distribuir c�pias - do software, ou modific�-lo. - - Por exemplo, se voc� distribuir c�pias de um programa sobre este tipo de - licenciamento, gratuitamente ou por alguma quantia, tem que fornecer igualmente - todos os direitos que possui sobre ele. Tem igualmente que garantir que os - destinat�rios recebam ou possam obter o c�digo-fonte. Al�m disto, tem que - fornecer-lhes estes termos para que possam conhecer seus direitos. - - N�s protegemos seus direitos por duas formas que se completam: (1) com - copyright do software e (2) com a oferta desta licen�a, que lhe d� permiss�o - legal para copiar, distribuir e/ou modificar o software. - - Al�m disso, tanto para a protec��o do autor quanto a nossa, gostar�amos de - certificar-nos de que todos entendam que n�o h� qualquer garantia sobre o - software livre. Se o software � modificado por algu�m e redistribu�do, queremos - que seus destinat�rios saibam que o que eles obtiveram n�o � original, de forma - que qualquer problema introduzido por terceiros n�o interfira na reputa��o do - autor original. - - Finalmente, qualquer programa � amea�ado constantemente por patentes de - software. Queremos evitar o perigo de que distribuidores de software livre - obtenham patentes individuais sobre o software, o que teria o efeito de tornar - o software propriet�rio. Para prevenir isso, deixamos claro que qualquer - patente tem que ser licenciada para uso livre e gratuito por qualquer pessoa, - ou ent�o que nem necessite ser licenciada. - - Os termos e condi��es precisas para c�pia, distribui��o e modifica��o - encontram-se abaixo: - -LICEN�A P�BLICA GERAL GNU TERMOS E CONDI��ES PARA C�PIA, DISTRIBUI��O E -MODIFICA��O - - 0. Esta licen�a aplica-se a qualquer programa ou outro trabalho que contenha um - aviso colocado pelo detentor dos direitos autorais informando que aquele pode - ser distribu�do sob as condi��es desta Licen�a P�blica Geral. O "Programa" - abaixo refere-se a qualquer programa ou trabalho e "trabalho baseado no - Programa" significa tanto o Programa em si, como quaisquer trabalhos derivados, - de acordo com a lei de direitos de autor: isto quer dizer um trabalho que - contenha o Programa ou parte dele, tanto na forma original ou modificado, e/ou - tradu��o para outros idiomas. ***(Doravante o termo "modifica��o" ou sin�nimos - ser�o usados livremente.) *** Cada licenciado � mencionado como "voc�". - - Actividades outras que a c�pia, a distribui��o e modifica��o n�o est�o cobertas - por esta Licen�a; elas est�o fora do seu �mbito. O acto de executar o Programa - n�o � restringido e o resultado do Programa � coberto pela licen�a apenas se o - seu conte�do contenha trabalhos baseados no Programa (independentemente de - terem sido gerados pela execu��o do Programa). Este �ltimo ponto depende das - funcionalidades espec�ficas de cada programa. - - 1. Voc� pode copiar e distribuir c�pias fi�is do c�digo-fonte do Programa da - mesma forma que voc� o recebeu, usando qualquer meio, deste que inclua em cada - c�pia um aviso de direitos de autor e uma declara��o de inexist�ncia de - garantias; mantenha intactos todos os avisos que se referem a esta Licen�a e � - aus�ncia total de garantias; e forne�a aos destinat�rios do Programa uma c�pia - desta Licen�a, em conjunto com o Programa. - - Voc� pode cobrar pelo acto f�sico de transferir uma c�pia e pode, - opcionalmente, oferecer garantias em troca de pagamento. - - 2. Voc� pode modificar sua c�pia ou c�pias do Programa, ou qualquer parte dele, - gerando assim um trabalho derivado, copiar e distribuir essas modifica��es ou - trabalhos sob os termos da sec��o 1 acima, desde que se enquadre nas seguintes - condi��es: - - a) Os arquivos modificados devem conter avisos proeminentes afirmando que voc� - alterou os arquivos, incluindo a data de qualquer altera��o. - - b) Deve ser licenciado, sob os termos desta Licen�a, integralmente e sem custo - algum para terceiros, qualquer trabalho seu que contenha ou seja derivado do - Programa ou de parte dele. - - c) Se qualquer programa modificado, quando executado, l� normalmente comandos - interactivamente, tem que fazer com que, quando iniciado o uso interactivo, - seja impresso ou mostrado um an�ncio de que n�o h� qualquer garantia (ou ent�o - que voc� fornece a garantia) e que os utilizadores podem redistribuir o - programa sob estas condi��es, ainda informando os utilizadores como consultar - uma c�pia desta Licen�a. (Excep��o: se o Programa em si � interactivo mas - normalmente n�o imprime estes tipos de an�ncios, ent�o o seu trabalho derivado - n�o precisa imprimir um an�ncio.) - - Estas exig�ncias aplicam-se ao trabalho derivado como um todo. Se sec��es - identific�veis de tal trabalho n�o s�o derivadas do Programa, e podem ser - razoavelmente consideradas trabalhos independentes e separados por si s�, ent�o - esta Licen�a, e seus termos, n�o se aplicam a estas sec��es caso as distribua - como um trabalho separado. Mas se distribuir as mesmas sec��es como parte de um - todo que constitui trabalho derivado, a distribui��o como um todo tem que - enquadrar-se nos termos desta Licen�a, cujos direitos para outros licenciados - se estendem ao todo, portanto tamb�m para toda e qualquer parte do programa, - independente de quem a escreveu. - - Desta forma, esta sec��o n�o tem a inten��o de reclamar direitos ou contestar - seus direitos sobre o trabalho escrito completamente por si; ao inv�s disso, a - inten��o � a de exercitar o direito de controlar a distribui��o de trabalhos, - derivados ou colectivos, baseados no Programa. - - Adicionalmente, a mera adi��o ao Programa (ou a um trabalho derivado deste) de - um outro trabalho num volume de armazenamento ou meio de distribui��o n�o faz - esse outro trabalho seja inclu�do no �mbito desta Licen�a. - - 3. Voc� pode copiar e distribuir o Programa (ou trabalho derivado, conforme - descrito na Sec��o 2) em c�digo-objecto ou em forma execut�vel sob os termos - das Sec��es 1 e 2 acima, desde que cumpra uma das seguintes alienas: - - a) O fa�a acompanhar com o c�digo-fonte completo e em forma acess�vel por - m�quinas, c�digo esse que tem que ser distribu�do sob os termos das Sec��es 1 e - 2 acima e em meio normalmente utilizado para o interc�mbio de software; ou, - - b) O acompanhe com uma oferta escrita, v�lida por pelo menos tr�s anos, de - fornecer a qualquer um, com um custo n�o superior ao custo de distribui��o - f�sica do material, uma c�pia do c�digo-fonte completo e em forma acess�vel por - m�quinas, c�digo esse que tem que ser distribu�do sob os termos das Sec��es 1 - e 2 acima e em meio normalmente utilizado para o interc�mbio de software; ou, - - c) O acompanhe com a informa��o que voc� recebeu em rela��o � oferta de - distribui��o do c�digo-fonte correspondente. (Esta alternativa � permitida - somente em distribui��o n�o comerciais, e apenas se voc� recebeu o programa em - forma de c�digo-objecto ou execut�vel, com uma oferta de acordo com a Subsec��o - b) acima.) - - O c�digo-fonte de um trabalho corresponde � forma de trabalho preferida para se - fazer modifica��es. Para um trabalho em forma execut�vel, o c�digo-fonte - completo significa todo o c�digo-fonte de todos os m�dulos que ele cont�m, mais - quaisquer arquivos de defini��o de "interface", mais os "scripts" utilizados - para se controlar a compila��o e a instala��o do execut�vel. Contudo, como - excep��o especial, o c�digo-fonte distribu�do n�o precisa incluir qualquer - componente normalmente distribu�do (tanto em forma original quanto bin�ria) com - os maiores componentes (o compilador, o "kernel" etc.) do sistema operativo sob - o qual o execut�vel funciona, a menos que o componente em si acompanhe o - execut�vel. - - Se a distribui��o do execut�vel ou c�digo-objecto � feita atrav�s da oferta de - acesso a c�pias em algum lugar, ent�o oferecer o acesso equivalente a c�pia, no - mesmo lugar, do c�digo-fonte, equivale � distribui��o do c�digo-fonte, mesmo - que terceiros n�o sejam compelidos a copiar o c�digo-fonte em conjunto com o - c�digo-objecto. - - 4. Voc� n�o pode copiar, modificar, sublicenciar ou distribuir o Programa, - excepto de acordo com as condi��es expressas nesta Licen�a. Qualquer outra - tentativa de c�pia, modifica��o, sublicenciamento ou distribui��o do Programa - n�o � valida, e cancelar� automaticamente os direitos que lhe foram fornecidos - por esta Licen�a. No entanto, terceiros que receberam de si c�pias ou direitos, - fornecidos sob os termos desta Licen�a, n�o ter�o a sua licen�a terminada, - desde que permane�am em total concord�ncia com ela. - - 5. Voc� n�o � obrigado a aceitar esta Licen�a j� que n�o a assinou. No entanto, - nada mais lhe dar� permiss�o para modificar ou distribuir o Programa ou - trabalhos derivados deste. Estas ac��es s�o proibidas por lei, caso voc� n�o - aceite esta Licen�a. Desta forma, ao modificar ou distribuir o Programa (ou - qualquer trabalho derivado do Programa), voc� estar� a indicar a sua total - concord�ncia com os termos desta Licen�a, nomeadamente os termos e condi��es - para copiar, distribuir ou modificar o Programa, ou trabalhos baseados nele. - - 6. Cada vez que redistribuir o Programa (ou qualquer trabalho derivado), os - destinat�rios adquirir�o automaticamente do autor original uma licen�a para - copiar, distribuir ou modificar o Programa, sujeitos a estes termos e - condi��es. Voc� n�o poder� impor aos destinat�rios qualquer outra restri��o ao - exerc�cio dos direitos ent�o adquiridos. Voc� n�o � respons�vel em garantir a - concord�ncia de terceiros a esta Licen�a. - - 7. Se, em consequ�ncia de decis�es judiciais ou alega��es de viola��o de - patentes ou quaisquer outras raz�es (n�o limitadas a assuntos relacionados a - patentes), lhe forem impostas condi��es (por ordem judicial, acordos ou outras - formas) e que contradigam as condi��es desta Licen�a, elas n�o o livram das - condi��es desta Licen�a. Se n�o puder distribuir de forma a satisfazer - simultaneamente suas obriga��es para com esta Licen�a e para com as outras - obriga��es pertinentes, ent�o como consequ�ncia voc� n�o poder� distribuir o - Programa. Por exemplo, se uma licen�a de patente n�o permitir a redistribui��o, - sem obriga��o ao pagamento de "royalties", por todos aqueles que receberem - c�pias directa ou indirectamente de si, ent�o a �nica forma de voc� satisfazer - a licen�a de patente e a esta Licen�a seria a de desistir completamente de - distribuir o Programa. - - Se qualquer parte desta sec��o for considerada inv�lida ou n�o aplic�vel em - qualquer circunst�ncia particular, o restante da sec��o aplica-se, e a sec��o - como um todo aplicar-se-� em outras circunst�ncias. - - O prop�sito desta sec��o n�o � o de induzi-lo a infringir quaisquer patentes ou - reivindica��o de direitos de propriedade de outros, ou a contestar a validade - de quaisquer dessas reivindica��es; esta sec��o tem como �nico prop�sito - proteger a integridade dos sistemas de distribui��o de software livre, que � - implementado pela pr�tica de licen�as p�blicas. V�rias pessoas t�m contribu�do - generosamente e em grande escala para software distribu�do usando este sistema, - na certeza de que sua aplica��o � feita de forma consistente; fica a crit�rio - do autor/doador decidir se ele ou ela est� disposto(a) a distribuir software - utilizando outro sistema, e um outro detentor de uma licen�a n�o pode impor - esta ou qualquer outra escolha. - - Esta sec��o destina-se a tornar bastante claro o que se acredita ser - consequ�ncia do restante desta Licen�a. - - 8. Se a distribui��o e/ou uso do Programa s�o restringidos em certos pa�ses por - patentes ou direitos de autor, o detentor dos direitos de autor original, que - colocou o Programa sob esta Licen�a, pode incluir uma limita��o geogr�fica de - distribui��o, excluindo aqueles pa�ses, de forma a apenas permitir a - distribui��o nos pa�ses n�o exclu�dos. Nestes casos, esta Licen�a incorpora a - limita��o como se a mesma constasse escrita nesta Licen�a. - - 9. A Free Software Foundation pode publicar vers�es revistas e/ou novas da - Licen�a P�blica Geral de tempos em tempos. Estas novas vers�es ser�o similares - em esp�rito � vers�o actual, mas podem diferir em detalhes que resolvam novos - problemas ou situa��es. - - A cada vers�o � dada um n�mero distinto. Se o Programa especifica um n�mero de - vers�o espec�fico desta Licen�a que se aplica a ele e a "qualquer nova vers�o", - voc� tem a op��o de aceitar os termos e condi��es daquela vers�o ou de qualquer - outra vers�o posterior publicada pela Free Software Foundation. Se o programa - n�o especificar um n�mero de vers�o desta Licen�a, poder� escolher qualquer - vers�o publicada pela Free Software Foundation. - - 10. Se voc� pretende incorporar partes do Programa em outros programas livres - cujas condi��es de distribui��o sejam diferentes, escreva ao autor e solicite - permiss�o para tal. Para o software que a Free Software Foundation det�m - direitos de autor, escreva � Free Software Foundation; �s vezes n�s permitimos - excep��es para estes casos. A nossa decis�o ser� guiada por dois objectivos: o - de preservar a condi��o de liberdade de todas os trabalhos derivados do nosso - software livre, e o de promover a partilha e reutiliza��o de software de um - modo geral. - - -AUS�NCIA DE GARANTIAS - - 11. UMA VEZ QUE O PROGRAMA � LICENCIADO SEM �NUS, N�O H� QUALQUER GARANTIA PARA - O PROGRAMA, NA EXTENS�O PERMITIDA PELAS LEIS APLIC�VEIS. EXCEPTO QUANDO - EXPRESSO DE FORMA ESCRITA, OS DETENTORES DOS DIREITOS AUTORAIS E/OU TERCEIROS - DISPONIBILIZAM O PROGRAMA "COMO ESTA", SEM QUALQUER TIPO DE GARANTIAS, - EXPRESSAS OU IMPL�CITAS, INCLUINDO, MAS N�O LIMITADO A, �S GARANTIAS IMPL�CITAS - DE COMERCIALIZA��O E �S DE ADEQUA��O A QUALQUER PROP�SITO. O RISCO COM A - QUALIDADE E DESEMPENHO DO PROGRAMA � TOTALMENTE SEU. CASO O PROGRAMA SE REVELE - DEFEITUOSO, VOC� ASSUME OS CUSTOS DE TODAS AS MANUTEN��ES, REPAROS E CORREC��ES - QUE JULGUE NECESS�RIAS. - - 12. EM NENHUMA CIRCUNST�NCIA, A MENOS QUE EXIGIDO PELAS LEIS APLIC�VEIS OU - ACORDO ESCRITO, OS DETENTORES DOS DIREITOS DE AUTOR, OU QUALQUER OUTRA PARTE - QUE POSSA MODIFICAR E/OU REDISTRIBUIR O PROGRAMA CONFORME PERMITIDO ACIMA, - SER�O RESPONSABILIZADOS POR SI OU POR SEU INTERM�DIO, POR DANOS, INCLUINDO - QUALQUER DANO EM GERAL, ESPECIAL, ACIDENTAL OU CONSEQUENTE, RESULTANTES DO USO - OU INCAPACIDADE DE USO DO PROGRAMA (INCLUINDO, MAS N�O LIMITADO A, A PERDA DE - DADOS OU DADOS TORNADOS INCORRECTOS, OU PERDAS SOFRIDAS POR SI OU POR OUTRAS - PARTES, OU FALHAS DO PROGRAMA AO OPERAR COM QUALQUER OUTRO PROGRAMA), MESMO QUE - TAIS DETENTORES OU PARTES TENHAM SIDO AVISADOS DA POSSIBILIDADE DE TAIS DANOS. - -FIM DOS TERMOS E CONDI��ES - ---------------------- - - - -Como Aplicar Estes Termos aos Seus Novos Programas - - Se voc� desenvolver um novo programa, e quer que ele seja utilizado amplamente - pelo p�blico, a melhor forma de alcan�ar este objectivo � torn�-lo software - livre, software que qualquer um pode redistribuir e alterar, sob estes termos. - - Para tal, inclua os seguintes avisos no programa. � mais seguro inclui-los logo - no in�cio de cada arquivo-fonte para refor�ar mais efectivamente a inexist�ncia - de garantias; e cada arquivo deve conter pelo menos a linha de "copyright" e - uma indica��o sobre onde encontrar o texto completo da licen�a. - -Exemplo: - - - <uma linha que forne�a o nome do programa e uma ideia do que ele faz.> - Copyright (C) <ano> <nome do autor> - - Este programa � software livre; voc� pode redistribu�-lo e/ou modific�-lo sob - os termos da Licen�a P�blica Geral GNU, conforme publicada pela Free Software - Foundation; tanto a vers�o 2 da Licen�a como (a seu crit�rio) qualquer vers�o - mais actual. - - Este programa � distribu�do na expectativa de ser �til, mas SEM QUALQUER - GARANTIA; incluindo as garantias impl�citas de COMERCIALIZA��O ou de ADEQUA��O - A QUALQUER PROP�SITO EM PARTICULAR. Consulte a Licen�a P�blica Geral GNU para - obter mais detalhes. - - Voc� deve ter recebido uma c�pia da Licen�a P�blica Geral GNU em conjunto com - este programa; caso contr�rio, escreva para a Free Software Foundation, Inc., - 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - - - - Inclua tamb�m informa��es sobre como contact�-lo electronicamente e por carta. - - Se o programa � interactivo, fa�a-o mostrar um aviso breve como este, ao - iniciar um modo interactivo: - -Exemplo: - - - Gnomovision vers�o 69, Copyright (C) <ano> <nome do autor> O Gnomovision n�o - possui QUALQUER GARANTIA; para obter mais detalhes escreva `mostrar g'. � - software livre e voc� est� convidado a redistribui-lo sob certas condi��es; - digite `mostrar c' para obter detalhes. - - Os comandos hipot�ticos `mostrar g e `mostrar c' devem mostrar as partes - apropriadas da Licen�a P�blica Geral. � claro que os comandos que escolher usar - podem ser activados de outra forma que `mostrar g' e `mostrar c'; podem ser - cliques do rato ou itens de um menu -- o que melhor se adequar ao seu programa. - - Voc� tamb�m deve obter da sua entidade patronal (se trabalhar como - programador) ou escola, conforme o caso, uma "declara��o de aus�ncia de - direitos autorais" sobre o programa, se necess�rio. Aqui est� um exemplo: - - - Neoscopio Lda., declara a aus�ncia de quaisquer direitos autorais sobre o - programa `Gnomovision' escrito por Jorge Andrade. - -10 de Junho de 2004 - <assinatura de Miguel Nunes>, - -Miguel Nunes, Gerente de Neoscopio Lda. - - - - Esta Licen�a P�blica Geral n�o permite incorporar o seu programa em programas - propriet�rios. Se o seu programa � uma biblioteca de sub-rotinas, poder� - considerar mais �til permitir ligar aplica��es propriet�rias com a biblioteca. - Se � isto que pretende, use a Licen�a P�blica Geral de Bibliotecas GNU, em vez - desta Licen�a. - - - - - - +LICEN�A P�BLICA GERAL GNU +Vers�o 2, junho de 1991 + + This is an unofficial translation of the GNU General Public License into + Portuguese. It was not published by the Free Software Foundation, and does not + legally state the distribution terms for software that uses the GNU GPL -- only + the original English text of the GNU GPL does that. However, we hope that this + translation will help Portuguese speakers understand the GNU GPL better. + + Esta � uma tradu��o n�o-oficial da Licen�a P�blica Geral GNU ("GPL GNU") para + Portugu�s. N�o foi publicada pela Free Software Foundation, e legalmente n�o + afirma os termos de distribui��o de software que utilize a GPL GNU -- apenas o + texto original da GPL GNU, em ingl�s, faz isso. Contudo, esperamos que esta + tradu��o ajude aos que falam portugu�s a entender melhor a GPL GNU. + +Para sugest�es ou correc��es a esta tradu��o, contacte: + +miguel.andrade@neoscopio.com + + +--- Tradu��o do documento original a partir desta linha --- + + +LICEN�A P�BLICA GERAL GNU +Vers�o 2, junho de 1991 + + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, + Cambridge, MA 02139, USA + + A qualquer pessoa � permitido copiar e distribuir c�pias deste documento de + licen�a, desde que sem qualquer altera��o. + +Introdu��o + + As licen�as de software s�o normalmente desenvolvidas para restringir a + liberdade de compartilh�-lo e modifica-lo. Pelo contr�rio, a Licen�a P�blica + Geral GNU pretende garantir a sua liberdade de compartilhar e modificar o + software livre -- garantindo que o software ser� livre para os seus + utilizadores. Esta Licen�a P�blica Geral aplica-se � maioria do software da + Free Software Foundation e a qualquer outro programa ao qual o seu autor decida + aplic�-la. (Algum software da FSF � cobertos pela Licen�a P�blica Geral de + Bibliotecas.) Tamb�m poder� aplic�-la aos seus programas. + + Quando nos referimos a software livre, estamo-nos a referir � liberdade e n�o + ao pre�o. A Licen�a P�blica Geral (GPL - General Public Licence - em Ingl�s.) + foi desenvolvida para garantir a sua liberdade de distribuir c�pias de software + livre (e cobrar por isso, se quiser); receber o c�digo-fonte ou ter acesso a + ele, se quiser; poder modificar o software ou utilizar partes dele em novos + programas livres; e que saiba que est� no seu direito de o fazer. + + Para proteger seus direitos, precisamos fazer restri��es que impe�am a qualquer + um negar estes direitos ou solicitar que voc� abdique deles. Estas restri��es + traduzem-se em certas responsabilidades para si, caso venha a distribuir c�pias + do software, ou modific�-lo. + + Por exemplo, se voc� distribuir c�pias de um programa sobre este tipo de + licenciamento, gratuitamente ou por alguma quantia, tem que fornecer igualmente + todos os direitos que possui sobre ele. Tem igualmente que garantir que os + destinat�rios recebam ou possam obter o c�digo-fonte. Al�m disto, tem que + fornecer-lhes estes termos para que possam conhecer seus direitos. + + N�s protegemos seus direitos por duas formas que se completam: (1) com + copyright do software e (2) com a oferta desta licen�a, que lhe d� permiss�o + legal para copiar, distribuir e/ou modificar o software. + + Al�m disso, tanto para a protec��o do autor quanto a nossa, gostar�amos de + certificar-nos de que todos entendam que n�o h� qualquer garantia sobre o + software livre. Se o software � modificado por algu�m e redistribu�do, queremos + que seus destinat�rios saibam que o que eles obtiveram n�o � original, de forma + que qualquer problema introduzido por terceiros n�o interfira na reputa��o do + autor original. + + Finalmente, qualquer programa � amea�ado constantemente por patentes de + software. Queremos evitar o perigo de que distribuidores de software livre + obtenham patentes individuais sobre o software, o que teria o efeito de tornar + o software propriet�rio. Para prevenir isso, deixamos claro que qualquer + patente tem que ser licenciada para uso livre e gratuito por qualquer pessoa, + ou ent�o que nem necessite ser licenciada. + + Os termos e condi��es precisas para c�pia, distribui��o e modifica��o + encontram-se abaixo: + +LICEN�A P�BLICA GERAL GNU TERMOS E CONDI��ES PARA C�PIA, DISTRIBUI��O E +MODIFICA��O + + 0. Esta licen�a aplica-se a qualquer programa ou outro trabalho que contenha um + aviso colocado pelo detentor dos direitos autorais informando que aquele pode + ser distribu�do sob as condi��es desta Licen�a P�blica Geral. O "Programa" + abaixo refere-se a qualquer programa ou trabalho e "trabalho baseado no + Programa" significa tanto o Programa em si, como quaisquer trabalhos derivados, + de acordo com a lei de direitos de autor: isto quer dizer um trabalho que + contenha o Programa ou parte dele, tanto na forma original ou modificado, e/ou + tradu��o para outros idiomas. ***(Doravante o termo "modifica��o" ou sin�nimos + ser�o usados livremente.) *** Cada licenciado � mencionado como "voc�". + + Actividades outras que a c�pia, a distribui��o e modifica��o n�o est�o cobertas + por esta Licen�a; elas est�o fora do seu �mbito. O acto de executar o Programa + n�o � restringido e o resultado do Programa � coberto pela licen�a apenas se o + seu conte�do contenha trabalhos baseados no Programa (independentemente de + terem sido gerados pela execu��o do Programa). Este �ltimo ponto depende das + funcionalidades espec�ficas de cada programa. + + 1. Voc� pode copiar e distribuir c�pias fi�is do c�digo-fonte do Programa da + mesma forma que voc� o recebeu, usando qualquer meio, deste que inclua em cada + c�pia um aviso de direitos de autor e uma declara��o de inexist�ncia de + garantias; mantenha intactos todos os avisos que se referem a esta Licen�a e � + aus�ncia total de garantias; e forne�a aos destinat�rios do Programa uma c�pia + desta Licen�a, em conjunto com o Programa. + + Voc� pode cobrar pelo acto f�sico de transferir uma c�pia e pode, + opcionalmente, oferecer garantias em troca de pagamento. + + 2. Voc� pode modificar sua c�pia ou c�pias do Programa, ou qualquer parte dele, + gerando assim um trabalho derivado, copiar e distribuir essas modifica��es ou + trabalhos sob os termos da sec��o 1 acima, desde que se enquadre nas seguintes + condi��es: + + a) Os arquivos modificados devem conter avisos proeminentes afirmando que voc� + alterou os arquivos, incluindo a data de qualquer altera��o. + + b) Deve ser licenciado, sob os termos desta Licen�a, integralmente e sem custo + algum para terceiros, qualquer trabalho seu que contenha ou seja derivado do + Programa ou de parte dele. + + c) Se qualquer programa modificado, quando executado, l� normalmente comandos + interactivamente, tem que fazer com que, quando iniciado o uso interactivo, + seja impresso ou mostrado um an�ncio de que n�o h� qualquer garantia (ou ent�o + que voc� fornece a garantia) e que os utilizadores podem redistribuir o + programa sob estas condi��es, ainda informando os utilizadores como consultar + uma c�pia desta Licen�a. (Excep��o: se o Programa em si � interactivo mas + normalmente n�o imprime estes tipos de an�ncios, ent�o o seu trabalho derivado + n�o precisa imprimir um an�ncio.) + + Estas exig�ncias aplicam-se ao trabalho derivado como um todo. Se sec��es + identific�veis de tal trabalho n�o s�o derivadas do Programa, e podem ser + razoavelmente consideradas trabalhos independentes e separados por si s�, ent�o + esta Licen�a, e seus termos, n�o se aplicam a estas sec��es caso as distribua + como um trabalho separado. Mas se distribuir as mesmas sec��es como parte de um + todo que constitui trabalho derivado, a distribui��o como um todo tem que + enquadrar-se nos termos desta Licen�a, cujos direitos para outros licenciados + se estendem ao todo, portanto tamb�m para toda e qualquer parte do programa, + independente de quem a escreveu. + + Desta forma, esta sec��o n�o tem a inten��o de reclamar direitos ou contestar + seus direitos sobre o trabalho escrito completamente por si; ao inv�s disso, a + inten��o � a de exercitar o direito de controlar a distribui��o de trabalhos, + derivados ou colectivos, baseados no Programa. + + Adicionalmente, a mera adi��o ao Programa (ou a um trabalho derivado deste) de + um outro trabalho num volume de armazenamento ou meio de distribui��o n�o faz + esse outro trabalho seja inclu�do no �mbito desta Licen�a. + + 3. Voc� pode copiar e distribuir o Programa (ou trabalho derivado, conforme + descrito na Sec��o 2) em c�digo-objecto ou em forma execut�vel sob os termos + das Sec��es 1 e 2 acima, desde que cumpra uma das seguintes alienas: + + a) O fa�a acompanhar com o c�digo-fonte completo e em forma acess�vel por + m�quinas, c�digo esse que tem que ser distribu�do sob os termos das Sec��es 1 e + 2 acima e em meio normalmente utilizado para o interc�mbio de software; ou, + + b) O acompanhe com uma oferta escrita, v�lida por pelo menos tr�s anos, de + fornecer a qualquer um, com um custo n�o superior ao custo de distribui��o + f�sica do material, uma c�pia do c�digo-fonte completo e em forma acess�vel por + m�quinas, c�digo esse que tem que ser distribu�do sob os termos das Sec��es 1 + e 2 acima e em meio normalmente utilizado para o interc�mbio de software; ou, + + c) O acompanhe com a informa��o que voc� recebeu em rela��o � oferta de + distribui��o do c�digo-fonte correspondente. (Esta alternativa � permitida + somente em distribui��o n�o comerciais, e apenas se voc� recebeu o programa em + forma de c�digo-objecto ou execut�vel, com uma oferta de acordo com a Subsec��o + b) acima.) + + O c�digo-fonte de um trabalho corresponde � forma de trabalho preferida para se + fazer modifica��es. Para um trabalho em forma execut�vel, o c�digo-fonte + completo significa todo o c�digo-fonte de todos os m�dulos que ele cont�m, mais + quaisquer arquivos de defini��o de "interface", mais os "scripts" utilizados + para se controlar a compila��o e a instala��o do execut�vel. Contudo, como + excep��o especial, o c�digo-fonte distribu�do n�o precisa incluir qualquer + componente normalmente distribu�do (tanto em forma original quanto bin�ria) com + os maiores componentes (o compilador, o "kernel" etc.) do sistema operativo sob + o qual o execut�vel funciona, a menos que o componente em si acompanhe o + execut�vel. + + Se a distribui��o do execut�vel ou c�digo-objecto � feita atrav�s da oferta de + acesso a c�pias em algum lugar, ent�o oferecer o acesso equivalente a c�pia, no + mesmo lugar, do c�digo-fonte, equivale � distribui��o do c�digo-fonte, mesmo + que terceiros n�o sejam compelidos a copiar o c�digo-fonte em conjunto com o + c�digo-objecto. + + 4. Voc� n�o pode copiar, modificar, sublicenciar ou distribuir o Programa, + excepto de acordo com as condi��es expressas nesta Licen�a. Qualquer outra + tentativa de c�pia, modifica��o, sublicenciamento ou distribui��o do Programa + n�o � valida, e cancelar� automaticamente os direitos que lhe foram fornecidos + por esta Licen�a. No entanto, terceiros que receberam de si c�pias ou direitos, + fornecidos sob os termos desta Licen�a, n�o ter�o a sua licen�a terminada, + desde que permane�am em total concord�ncia com ela. + + 5. Voc� n�o � obrigado a aceitar esta Licen�a j� que n�o a assinou. No entanto, + nada mais lhe dar� permiss�o para modificar ou distribuir o Programa ou + trabalhos derivados deste. Estas ac��es s�o proibidas por lei, caso voc� n�o + aceite esta Licen�a. Desta forma, ao modificar ou distribuir o Programa (ou + qualquer trabalho derivado do Programa), voc� estar� a indicar a sua total + concord�ncia com os termos desta Licen�a, nomeadamente os termos e condi��es + para copiar, distribuir ou modificar o Programa, ou trabalhos baseados nele. + + 6. Cada vez que redistribuir o Programa (ou qualquer trabalho derivado), os + destinat�rios adquirir�o automaticamente do autor original uma licen�a para + copiar, distribuir ou modificar o Programa, sujeitos a estes termos e + condi��es. Voc� n�o poder� impor aos destinat�rios qualquer outra restri��o ao + exerc�cio dos direitos ent�o adquiridos. Voc� n�o � respons�vel em garantir a + concord�ncia de terceiros a esta Licen�a. + + 7. Se, em consequ�ncia de decis�es judiciais ou alega��es de viola��o de + patentes ou quaisquer outras raz�es (n�o limitadas a assuntos relacionados a + patentes), lhe forem impostas condi��es (por ordem judicial, acordos ou outras + formas) e que contradigam as condi��es desta Licen�a, elas n�o o livram das + condi��es desta Licen�a. Se n�o puder distribuir de forma a satisfazer + simultaneamente suas obriga��es para com esta Licen�a e para com as outras + obriga��es pertinentes, ent�o como consequ�ncia voc� n�o poder� distribuir o + Programa. Por exemplo, se uma licen�a de patente n�o permitir a redistribui��o, + sem obriga��o ao pagamento de "royalties", por todos aqueles que receberem + c�pias directa ou indirectamente de si, ent�o a �nica forma de voc� satisfazer + a licen�a de patente e a esta Licen�a seria a de desistir completamente de + distribuir o Programa. + + Se qualquer parte desta sec��o for considerada inv�lida ou n�o aplic�vel em + qualquer circunst�ncia particular, o restante da sec��o aplica-se, e a sec��o + como um todo aplicar-se-� em outras circunst�ncias. + + O prop�sito desta sec��o n�o � o de induzi-lo a infringir quaisquer patentes ou + reivindica��o de direitos de propriedade de outros, ou a contestar a validade + de quaisquer dessas reivindica��es; esta sec��o tem como �nico prop�sito + proteger a integridade dos sistemas de distribui��o de software livre, que � + implementado pela pr�tica de licen�as p�blicas. V�rias pessoas t�m contribu�do + generosamente e em grande escala para software distribu�do usando este sistema, + na certeza de que sua aplica��o � feita de forma consistente; fica a crit�rio + do autor/doador decidir se ele ou ela est� disposto(a) a distribuir software + utilizando outro sistema, e um outro detentor de uma licen�a n�o pode impor + esta ou qualquer outra escolha. + + Esta sec��o destina-se a tornar bastante claro o que se acredita ser + consequ�ncia do restante desta Licen�a. + + 8. Se a distribui��o e/ou uso do Programa s�o restringidos em certos pa�ses por + patentes ou direitos de autor, o detentor dos direitos de autor original, que + colocou o Programa sob esta Licen�a, pode incluir uma limita��o geogr�fica de + distribui��o, excluindo aqueles pa�ses, de forma a apenas permitir a + distribui��o nos pa�ses n�o exclu�dos. Nestes casos, esta Licen�a incorpora a + limita��o como se a mesma constasse escrita nesta Licen�a. + + 9. A Free Software Foundation pode publicar vers�es revistas e/ou novas da + Licen�a P�blica Geral de tempos em tempos. Estas novas vers�es ser�o similares + em esp�rito � vers�o actual, mas podem diferir em detalhes que resolvam novos + problemas ou situa��es. + + A cada vers�o � dada um n�mero distinto. Se o Programa especifica um n�mero de + vers�o espec�fico desta Licen�a que se aplica a ele e a "qualquer nova vers�o", + voc� tem a op��o de aceitar os termos e condi��es daquela vers�o ou de qualquer + outra vers�o posterior publicada pela Free Software Foundation. Se o programa + n�o especificar um n�mero de vers�o desta Licen�a, poder� escolher qualquer + vers�o publicada pela Free Software Foundation. + + 10. Se voc� pretende incorporar partes do Programa em outros programas livres + cujas condi��es de distribui��o sejam diferentes, escreva ao autor e solicite + permiss�o para tal. Para o software que a Free Software Foundation det�m + direitos de autor, escreva � Free Software Foundation; �s vezes n�s permitimos + excep��es para estes casos. A nossa decis�o ser� guiada por dois objectivos: o + de preservar a condi��o de liberdade de todas os trabalhos derivados do nosso + software livre, e o de promover a partilha e reutiliza��o de software de um + modo geral. + + +AUS�NCIA DE GARANTIAS + + 11. UMA VEZ QUE O PROGRAMA � LICENCIADO SEM �NUS, N�O H� QUALQUER GARANTIA PARA + O PROGRAMA, NA EXTENS�O PERMITIDA PELAS LEIS APLIC�VEIS. EXCEPTO QUANDO + EXPRESSO DE FORMA ESCRITA, OS DETENTORES DOS DIREITOS AUTORAIS E/OU TERCEIROS + DISPONIBILIZAM O PROGRAMA "COMO ESTA", SEM QUALQUER TIPO DE GARANTIAS, + EXPRESSAS OU IMPL�CITAS, INCLUINDO, MAS N�O LIMITADO A, �S GARANTIAS IMPL�CITAS + DE COMERCIALIZA��O E �S DE ADEQUA��O A QUALQUER PROP�SITO. O RISCO COM A + QUALIDADE E DESEMPENHO DO PROGRAMA � TOTALMENTE SEU. CASO O PROGRAMA SE REVELE + DEFEITUOSO, VOC� ASSUME OS CUSTOS DE TODAS AS MANUTEN��ES, REPAROS E CORREC��ES + QUE JULGUE NECESS�RIAS. + + 12. EM NENHUMA CIRCUNST�NCIA, A MENOS QUE EXIGIDO PELAS LEIS APLIC�VEIS OU + ACORDO ESCRITO, OS DETENTORES DOS DIREITOS DE AUTOR, OU QUALQUER OUTRA PARTE + QUE POSSA MODIFICAR E/OU REDISTRIBUIR O PROGRAMA CONFORME PERMITIDO ACIMA, + SER�O RESPONSABILIZADOS POR SI OU POR SEU INTERM�DIO, POR DANOS, INCLUINDO + QUALQUER DANO EM GERAL, ESPECIAL, ACIDENTAL OU CONSEQUENTE, RESULTANTES DO USO + OU INCAPACIDADE DE USO DO PROGRAMA (INCLUINDO, MAS N�O LIMITADO A, A PERDA DE + DADOS OU DADOS TORNADOS INCORRECTOS, OU PERDAS SOFRIDAS POR SI OU POR OUTRAS + PARTES, OU FALHAS DO PROGRAMA AO OPERAR COM QUALQUER OUTRO PROGRAMA), MESMO QUE + TAIS DETENTORES OU PARTES TENHAM SIDO AVISADOS DA POSSIBILIDADE DE TAIS DANOS. + +FIM DOS TERMOS E CONDI��ES + +--------------------- + + + +Como Aplicar Estes Termos aos Seus Novos Programas + + Se voc� desenvolver um novo programa, e quer que ele seja utilizado amplamente + pelo p�blico, a melhor forma de alcan�ar este objectivo � torn�-lo software + livre, software que qualquer um pode redistribuir e alterar, sob estes termos. + + Para tal, inclua os seguintes avisos no programa. � mais seguro inclui-los logo + no in�cio de cada arquivo-fonte para refor�ar mais efectivamente a inexist�ncia + de garantias; e cada arquivo deve conter pelo menos a linha de "copyright" e + uma indica��o sobre onde encontrar o texto completo da licen�a. + +Exemplo: + + + <uma linha que forne�a o nome do programa e uma ideia do que ele faz.> + Copyright (C) <ano> <nome do autor> + + Este programa � software livre; voc� pode redistribu�-lo e/ou modific�-lo sob + os termos da Licen�a P�blica Geral GNU, conforme publicada pela Free Software + Foundation; tanto a vers�o 2 da Licen�a como (a seu crit�rio) qualquer vers�o + mais actual. + + Este programa � distribu�do na expectativa de ser �til, mas SEM QUALQUER + GARANTIA; incluindo as garantias impl�citas de COMERCIALIZA��O ou de ADEQUA��O + A QUALQUER PROP�SITO EM PARTICULAR. Consulte a Licen�a P�blica Geral GNU para + obter mais detalhes. + + Voc� deve ter recebido uma c�pia da Licen�a P�blica Geral GNU em conjunto com + este programa; caso contr�rio, escreva para a Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + + + + Inclua tamb�m informa��es sobre como contact�-lo electronicamente e por carta. + + Se o programa � interactivo, fa�a-o mostrar um aviso breve como este, ao + iniciar um modo interactivo: + +Exemplo: + + + Gnomovision vers�o 69, Copyright (C) <ano> <nome do autor> O Gnomovision n�o + possui QUALQUER GARANTIA; para obter mais detalhes escreva `mostrar g'. � + software livre e voc� est� convidado a redistribui-lo sob certas condi��es; + digite `mostrar c' para obter detalhes. + + Os comandos hipot�ticos `mostrar g e `mostrar c' devem mostrar as partes + apropriadas da Licen�a P�blica Geral. � claro que os comandos que escolher usar + podem ser activados de outra forma que `mostrar g' e `mostrar c'; podem ser + cliques do rato ou itens de um menu -- o que melhor se adequar ao seu programa. + + Voc� tamb�m deve obter da sua entidade patronal (se trabalhar como + programador) ou escola, conforme o caso, uma "declara��o de aus�ncia de + direitos autorais" sobre o programa, se necess�rio. Aqui est� um exemplo: + + + Neoscopio Lda., declara a aus�ncia de quaisquer direitos autorais sobre o + programa `Gnomovision' escrito por Jorge Andrade. + +10 de Junho de 2004 + <assinatura de Miguel Nunes>, + +Miguel Nunes, Gerente de Neoscopio Lda. + + + + Esta Licen�a P�blica Geral n�o permite incorporar o seu programa em programas + propriet�rios. Se o seu programa � uma biblioteca de sub-rotinas, poder� + considerar mais �til permitir ligar aplica��es propriet�rias com a biblioteca. + Se � isto que pretende, use a Licen�a P�blica Geral de Bibliotecas GNU, em vez + desta Licen�a. + + + + + + diff --git a/htdocs/langs/pt_PT/suppliers.lang b/htdocs/langs/pt_PT/suppliers.lang index 1b6073bb4d43fcc300464b8befd69d62b1afb8ef..3c6d055c838cc34dc7c9f10448f563433ba55e63 100644 --- a/htdocs/langs/pt_PT/suppliers.lang +++ b/htdocs/langs/pt_PT/suppliers.lang @@ -1,10 +1,10 @@ -# Dolibarr language file - pt_PT - fornecedores -Suppliers=Fornecedores -Supplier=Fornecedor -AddSupplier=Adicionar Fornecedor -SupplierRemoved=Fornecedor removido -NewSupplier=Novo fornecedor -History=Hist�ria -OrderCard=Cart�o de encomenda -ListOfSuppliers=Lista de fornecedores +# Dolibarr language file - pt_PT - fornecedores +Suppliers=Fornecedores +Supplier=Fornecedor +AddSupplier=Adicionar Fornecedor +SupplierRemoved=Fornecedor removido +NewSupplier=Novo fornecedor +History=Hist�ria +OrderCard=Cart�o de encomenda +ListOfSuppliers=Lista de fornecedores ShowSupplier=Mostrar fonecedor \ No newline at end of file diff --git a/htdocs/oscommerce_ws/ws_server/ws_orders.php b/htdocs/oscommerce_ws/ws_server/ws_orders.php index 3342ed07550b53cb29bcbede67b930b9d68eda29..b2e2fb29db76a1990312f22cf1e61c94e8a329bd 100644 --- a/htdocs/oscommerce_ws/ws_server/ws_orders.php +++ b/htdocs/oscommerce_ws/ws_server/ws_orders.php @@ -1,4 +1,4 @@ -<?php +<?php /* Copyright (C) 2006 Jean Heimburger <jean@tiaris.info> * * @@ -19,21 +19,21 @@ * $Source$ * */ -set_magic_quotes_runtime(0); - -// Soap Server. -require_once('./lib/nusoap.php'); +set_magic_quotes_runtime(0); + +// Soap Server. +require_once('./lib/nusoap.php'); require_once('./includes/configure.php'); - -// Create the soap Object -$s = new soap_server; - -// Register the methods available for clients + +// Create the soap Object +$s = new soap_server; + +// Register the methods available for clients $s->register('get_CAmensuel'); $s->register('get_orders'); $s->register('get_lastOrderClients'); -$s->register('get_Order'); +$s->register('get_Order'); /*---------------------------------------------- * renvoie un tableau avec le CA mensuel r�alis� @@ -41,7 +41,7 @@ $s->register('get_Order'); function get_CAmensuel() { //on se connecte - if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); + if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); if (!($db = mysql_select_db(DB_DATABASE, $connexion))) return new soap_fault("Server", "MySQL 2", mysql_error()); //la requ�te @@ -54,10 +54,10 @@ function get_CAmensuel() { if (!($resquer = mysql_query($sql,$connexion))) return new soap_fault("Server", "MySQL 3 ".$sql, mysql_error()); - switch ($numrows = mysql_numrows($resquer)) { - case 0 : - return new soap_fault("Server", "MySQL 4", $sql); - break; + switch ($numrows = mysql_numrows($resquer)) { + case 0 : + return new soap_fault("Server", "MySQL 4", $sql); + break; default : $i = 0; while ( $i < $numrows) { @@ -74,7 +74,7 @@ return $result; function get_orders($limit='', $status='') { //on se connecte - if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); + if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); if (!($db = mysql_select_db(DB_DATABASE, $connexion))) return new soap_fault("Server", "MySQL 2", mysql_error()); //on recherche @@ -88,10 +88,10 @@ if ($limit > 0) $sql .= " LIMIT ".$limit; if (!($resquer = mysql_query($sql,$connexion))) return new soap_fault("Server", "MySQL 3 ".$sql, mysql_error()); $result =''; - switch ($numrows = mysql_numrows($resquer)) { - case 0 : + switch ($numrows = mysql_numrows($resquer)) { + case 0 : //return new soap_fault("Server", "MySQL 4", "produit inexistant"); - break; + break; default : $i = 0; while ( $i < $numrows) { @@ -109,7 +109,7 @@ return $result; function get_lastOrderClients($id='',$name='',$limit='') { //on se connecte - if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); + if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); if (!($db = mysql_select_db(DB_DATABASE, $connexion))) return new soap_fault("Server", "MySQL 2", mysql_error()); //on recherche @@ -122,10 +122,10 @@ function get_lastOrderClients($id='',$name='',$limit='') { if (!($resquer = mysql_query($sql,$connexion))) return new soap_fault("Server", "MySQL 3 ".$sql, mysql_error()); $result =''; - switch ($numrows = mysql_numrows($resquer)) { - case 0 : + switch ($numrows = mysql_numrows($resquer)) { + case 0 : return new soap_fault("Server", "MySQL 4", "produit inexistant"); - break; + break; default : $i = 0; while ( $i < $numrows) { @@ -145,7 +145,7 @@ function get_Order($orderid="0") { //on se connecte - if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); + if (!($connexion = mysql_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD))) return new soap_fault("Server", "MySQL 1", "connection impossible"); if (!($db = mysql_select_db(DB_DATABASE, $connexion))) return new soap_fault("Server", "MySQL 2", mysql_error()); //on recherche la commande @@ -166,10 +166,10 @@ $sql .= " ORDER BY o.date_purchased desc"; if (!($resquer = mysql_query($sql,$connexion))) return new soap_fault("Server", "MySQL 3 ".$sql, mysql_error()); $result =''; - switch ($numrows = mysql_numrows($resquer)) { - case 0 : + switch ($numrows = mysql_numrows($resquer)) { + case 0 : return new soap_fault("Server", "MySQL 4", "commande inexistante ".$sql); - break; + break; default : $i = 0; while ( $i < $numrows) { @@ -190,10 +190,10 @@ if ($orderid > 0) if (!($resquer = mysql_query($sql,$connexion))) return new soap_fault("Server", "MySQL 3 ".$sql, mysql_error()); - switch ($numrows = mysql_numrows($resquer)) { - case 0 : + switch ($numrows = mysql_numrows($resquer)) { + case 0 : return new soap_fault("Server", "MySQL 5", "commande sans articles"); - break; + break; default : while ( $i < $numrows) { @@ -208,8 +208,8 @@ mysql_close($connexion); return $result; } - -// Return the results. + +// Return the results. $s->service($HTTP_RAW_POST_DATA); - -?> + +?> diff --git a/htdocs/telephonie/contrat/statut7.png b/htdocs/telephonie/contrat/statut7.png index 41ff0d4681d50528450935dfed6d62bf0b78ff1f..f1ad7558e4917c38d1dafc49f7bccac10219adee 100644 Binary files a/htdocs/telephonie/contrat/statut7.png and b/htdocs/telephonie/contrat/statut7.png differ diff --git a/htdocs/theme/auguria/fckeditor/images/.cvsignore b/htdocs/theme/auguria/fckeditor/images/.cvsignore index 020f386440732e66fc724c21c1af2b723a402f79..78d24c2393017b5f628370404fbb29c91ccccc47 100644 --- a/htdocs/theme/auguria/fckeditor/images/.cvsignore +++ b/htdocs/theme/auguria/fckeditor/images/.cvsignore @@ -1,2 +1,2 @@ -*.db -*.db +*.db +*.db diff --git a/htdocs/theme/auguria/img/.cvsignore b/htdocs/theme/auguria/img/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/auguria/img/.cvsignore +++ b/htdocs/theme/auguria/img/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/auguria/img/bouton/.cvsignore b/htdocs/theme/auguria/img/bouton/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/auguria/img/bouton/.cvsignore +++ b/htdocs/theme/auguria/img/bouton/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/dev/.cvsignore b/htdocs/theme/dev/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/dev/.cvsignore +++ b/htdocs/theme/dev/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/dolibarr/.cvsignore b/htdocs/theme/dolibarr/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/dolibarr/.cvsignore +++ b/htdocs/theme/dolibarr/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/dolibarr/img/filenew.png b/htdocs/theme/dolibarr/img/filenew.png index 7be37e89a77c4f6df269bd74b30d69ea2edd59a2..f1ad7558e4917c38d1dafc49f7bccac10219adee 100644 Binary files a/htdocs/theme/dolibarr/img/filenew.png and b/htdocs/theme/dolibarr/img/filenew.png differ diff --git a/htdocs/theme/eldy/.cvsignore b/htdocs/theme/eldy/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/eldy/.cvsignore +++ b/htdocs/theme/eldy/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/freelug/.cvsignore b/htdocs/theme/freelug/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/freelug/.cvsignore +++ b/htdocs/theme/freelug/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/freelug/fckeditor/images/.cvsignore b/htdocs/theme/freelug/fckeditor/images/.cvsignore index 020f386440732e66fc724c21c1af2b723a402f79..78d24c2393017b5f628370404fbb29c91ccccc47 100644 --- a/htdocs/theme/freelug/fckeditor/images/.cvsignore +++ b/htdocs/theme/freelug/fckeditor/images/.cvsignore @@ -1,2 +1,2 @@ -*.db -*.db +*.db +*.db diff --git a/htdocs/theme/freelug/img/.cvsignore b/htdocs/theme/freelug/img/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/freelug/img/.cvsignore +++ b/htdocs/theme/freelug/img/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/yellow/.cvsignore b/htdocs/theme/yellow/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/yellow/.cvsignore +++ b/htdocs/theme/yellow/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/htdocs/theme/yellow/fckeditor/images/.cvsignore b/htdocs/theme/yellow/fckeditor/images/.cvsignore index 020f386440732e66fc724c21c1af2b723a402f79..78d24c2393017b5f628370404fbb29c91ccccc47 100644 --- a/htdocs/theme/yellow/fckeditor/images/.cvsignore +++ b/htdocs/theme/yellow/fckeditor/images/.cvsignore @@ -1,2 +1,2 @@ -*.db -*.db +*.db +*.db diff --git a/htdocs/theme/yellow/img/.cvsignore b/htdocs/theme/yellow/img/.cvsignore index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644 --- a/htdocs/theme/yellow/img/.cvsignore +++ b/htdocs/theme/yellow/img/.cvsignore @@ -1 +1 @@ -*.db +*.db diff --git a/mysql/tables/llx_osc_categories.sql b/mysql/tables/llx_osc_categories.sql index 1534915c1515be719fc7d6662a382014c38e305a..d02e02855e7d8650fd77f53e4bdc3a2cfb636ab9 100644 --- a/mysql/tables/llx_osc_categories.sql +++ b/mysql/tables/llx_osc_categories.sql @@ -1,26 +1,26 @@ --- phpMyAdmin SQL Dump --- version 2.6.2-Debian-3sarge3 --- http://www.phpmyadmin.net --- --- Serveur: localhost --- G�n�r� le : Mercredi 20 Juin 2007 � 15:13 --- Version du serveur: 4.0.24 --- Version de PHP: 4.3.10-19 --- --- Base de donn�es: `dolidev` --- - --- -------------------------------------------------------- - --- --- Structure de la table `llx_osc_categories` --- - -CREATE TABLE llx_osc_categories ( - rowid int(11) unsigned NOT NULL auto_increment, - dolicatid int(11) NOT NULL default '0', - osccatid int(11) NOT NULL default '0', - PRIMARY KEY (rowid), - UNIQUE KEY dolicatid (dolicatid), - UNIQUE KEY osccatid (osccatid) -) TYPE=InnoDB COMMENT='Correspondance categorie Dolibarr categorie OSC'; +-- phpMyAdmin SQL Dump +-- version 2.6.2-Debian-3sarge3 +-- http://www.phpmyadmin.net +-- +-- Serveur: localhost +-- G�n�r� le : Mercredi 20 Juin 2007 � 15:13 +-- Version du serveur: 4.0.24 +-- Version de PHP: 4.3.10-19 +-- +-- Base de donn�es: `dolidev` +-- + +-- -------------------------------------------------------- + +-- +-- Structure de la table `llx_osc_categories` +-- + +CREATE TABLE llx_osc_categories ( + rowid int(11) unsigned NOT NULL auto_increment, + dolicatid int(11) NOT NULL default '0', + osccatid int(11) NOT NULL default '0', + PRIMARY KEY (rowid), + UNIQUE KEY dolicatid (dolicatid), + UNIQUE KEY osccatid (osccatid) +) TYPE=InnoDB COMMENT='Correspondance categorie Dolibarr categorie OSC'; diff --git a/pgsql/tables/llx_accountingaccount.key.sql b/pgsql/tables/llx_accountingaccount.key.sql index 243e83512744ac71012ea76c0f281feb7c20cbd9..98a69d9e99e68669939f4914d6c3ac75abbeb2bb 100644 --- a/pgsql/tables/llx_accountingaccount.key.sql +++ b/pgsql/tables/llx_accountingaccount.key.sql @@ -1,31 +1,31 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2005-2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- =========================================================================== - - -ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version); - - -ALTER TABLE llx_accountingaccount ADD CONSTRAINT fk_accountingaccount_fk_pcg_version FOREIGN KEY (fk_pcg_version) REFERENCES llx_accountingsystem (pcg_version); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2005-2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- =========================================================================== + + +ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version); + + +ALTER TABLE llx_accountingaccount ADD CONSTRAINT fk_accountingaccount_fk_pcg_version FOREIGN KEY (fk_pcg_version) REFERENCES llx_accountingsystem (pcg_version); diff --git a/pgsql/tables/llx_accountingaccount.sql b/pgsql/tables/llx_accountingaccount.sql index 4c792346bdc6fedc90abbdb890d40dc5c6bbe7e2..b69c0332c7d33e7efb5d93bd558e747d5a3a4f5b 100644 --- a/pgsql/tables/llx_accountingaccount.sql +++ b/pgsql/tables/llx_accountingaccount.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- ============================================================================ - -create table llx_accountingaccount -( - rowid SERIAL PRIMARY KEY, - "fk_pcg_version" varchar(12) NOT NULL, - "pcg_type" varchar(20) NOT NULL, - "pcg_subtype" varchar(20) NOT NULL, - "label" varchar(128) NOT NULL, - "account_number" varchar(20) NOT NULL, - "account_parent" varchar(20) -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- ============================================================================ + +create table llx_accountingaccount +( + rowid SERIAL PRIMARY KEY, + "fk_pcg_version" varchar(12) NOT NULL, + "pcg_type" varchar(20) NOT NULL, + "pcg_subtype" varchar(20) NOT NULL, + "label" varchar(128) NOT NULL, + "account_number" varchar(20) NOT NULL, + "account_parent" varchar(20) +); diff --git a/pgsql/tables/llx_accountingdebcred.sql b/pgsql/tables/llx_accountingdebcred.sql index 89daac20f3c95b9de6eba382413cfb339a8f9bee..1c67fe81cd5be624b3bfe3111fa1d7a06297460a 100644 --- a/pgsql/tables/llx_accountingdebcred.sql +++ b/pgsql/tables/llx_accountingdebcred.sql @@ -1,32 +1,32 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- ============================================================================ - -create table llx_accountingdebcred -( - "fk_transaction" integer NOT NULL, - "fk_account" integer NOT NULL, - "amount" real NOT NULL, - "direction" varchar(1) NOT NULL -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- ============================================================================ + +create table llx_accountingdebcred +( + "fk_transaction" integer NOT NULL, + "fk_account" integer NOT NULL, + "amount" real NOT NULL, + "direction" varchar(1) NOT NULL +); diff --git a/pgsql/tables/llx_accountingsystem.sql b/pgsql/tables/llx_accountingsystem.sql index 1258b76c9ed6f815a4e39e46147bcb8094d4505d..736f47019441cf99768a4b59dc7edde335d8676f 100644 --- a/pgsql/tables/llx_accountingsystem.sql +++ b/pgsql/tables/llx_accountingsystem.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- ============================================================================ - -create table llx_accountingsystem -( - pcg_version varchar(12) PRIMARY KEY, - "fk_pays" integer NOT NULL, - "label" varchar(128) NOT NULL, - "datec" varchar(12) NOT NULL, - "fk_author" varchar(20), - "tms" timestamp, - "active" smallint DEFAULT 0 -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- ============================================================================ + +create table llx_accountingsystem +( + pcg_version varchar(12) PRIMARY KEY, + "fk_pays" integer NOT NULL, + "label" varchar(128) NOT NULL, + "datec" varchar(12) NOT NULL, + "fk_author" varchar(20), + "tms" timestamp, + "active" smallint DEFAULT 0 +); diff --git a/pgsql/tables/llx_accountingtransaction.sql b/pgsql/tables/llx_accountingtransaction.sql index 38d05310c78d56a540a6c55e6293cfb77127dc6c..88790550464bef3a1b6627e6c7d9a1f964d4ee92 100644 --- a/pgsql/tables/llx_accountingtransaction.sql +++ b/pgsql/tables/llx_accountingtransaction.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- ============================================================================ - -create table llx_accountingtransaction -( - rowid SERIAL PRIMARY KEY, - "label" varchar(128) NOT NULL, - "datec" date NOT NULL, - "fk_author" varchar(20) NOT NULL, - "tms" timestamp, - "fk_facture" integer, - "fk_facture_fourn" integer, - "fk_paiement" integer, - "fk_paiement_fourn" integer -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- ============================================================================ + +create table llx_accountingtransaction +( + rowid SERIAL PRIMARY KEY, + "label" varchar(128) NOT NULL, + "datec" date NOT NULL, + "fk_author" varchar(20) NOT NULL, + "tms" timestamp, + "fk_facture" integer, + "fk_facture_fourn" integer, + "fk_paiement" integer, + "fk_paiement_fourn" integer +); diff --git a/pgsql/tables/llx_action_def.sql b/pgsql/tables/llx_action_def.sql index 99c9dceb3de4c303278da35ee15f7488af2c1269..9991464cd41d48c76b510802413e6393a3ef27d2 100644 --- a/pgsql/tables/llx_action_def.sql +++ b/pgsql/tables/llx_action_def.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be> --- Copyright (C) 2004 Guillaume Delecourt <guillaume.delecourt@opensides.be> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - -create table llx_action_def -( - rowid integer NOT NULL PRIMARY KEY, - "code" varchar(24) UNIQUE NOT NULL, - "tms" timestamp, - "titre" varchar(255) NOT NULL, - "description" text, - "objet_type" varchar(10) CHECK (objet_type IN ('ficheinter','facture','propale','mailing')) -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be> +-- Copyright (C) 2004 Guillaume Delecourt <guillaume.delecourt@opensides.be> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + +create table llx_action_def +( + rowid integer NOT NULL PRIMARY KEY, + "code" varchar(24) UNIQUE NOT NULL, + "tms" timestamp, + "titre" varchar(255) NOT NULL, + "description" text, + "objet_type" varchar(10) CHECK (objet_type IN ('ficheinter','facture','propale','mailing')) +); diff --git a/pgsql/tables/llx_actioncomm.key.sql b/pgsql/tables/llx_actioncomm.key.sql index f1071fbcaa8f4a6d0f91b8888f3406a05fb55499..886354ffd78490cf0d0de7c3646433d8eaefee33 100644 --- a/pgsql/tables/llx_actioncomm.key.sql +++ b/pgsql/tables/llx_actioncomm.key.sql @@ -1,31 +1,31 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =========================================================================== - - -ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datea (datea); -ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_soc (fk_soc); -ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_contact (fk_contact); -ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_facture (fk_facture); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =========================================================================== + + +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datea (datea); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_soc (fk_soc); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_contact (fk_contact); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_facture (fk_facture); diff --git a/pgsql/tables/llx_actioncomm.sql b/pgsql/tables/llx_actioncomm.sql index b0faa459e3afdb8ceacfaf267796284de61a6b69..6a70c462011f56262673b31fb1b5060dde5747b2 100644 --- a/pgsql/tables/llx_actioncomm.sql +++ b/pgsql/tables/llx_actioncomm.sql @@ -1,53 +1,53 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- Actions commerciales --- --- ======================================================================== - -create table llx_actioncomm -( - id SERIAL PRIMARY KEY, - "datec" timestamp, -- date creation - "datep" timestamp, -- date 0% - "datea" timestamp, -- date 100% - "tms" timestamp, -- date modif - "fk_action" integer, - "label" varchar(50) NOT NULL, -- libelle de l'action - "fk_soc" integer, - "fk_contact" integer default 0, - "fk_user_action" integer, -- id de la personne qui doit effectuer l'action - "fk_user_author" integer, - "priority" smallint, - "percent" smallint NOT NULL default 0, - "note" text, - "propalrowid" integer, - "fk_commande" integer, - "fk_facture" integer -); - - - - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- Actions commerciales +-- +-- ======================================================================== + +create table llx_actioncomm +( + id SERIAL PRIMARY KEY, + "datec" timestamp, -- date creation + "datep" timestamp, -- date 0% + "datea" timestamp, -- date 100% + "tms" timestamp, -- date modif + "fk_action" integer, + "label" varchar(50) NOT NULL, -- libelle de l'action + "fk_soc" integer, + "fk_contact" integer default 0, + "fk_user_action" integer, -- id de la personne qui doit effectuer l'action + "fk_user_author" integer, + "priority" smallint, + "percent" smallint NOT NULL default 0, + "note" text, + "propalrowid" integer, + "fk_commande" integer, + "fk_facture" integer +); + + + + diff --git a/pgsql/tables/llx_adherent.sql b/pgsql/tables/llx_adherent.sql index ef404764540dd26debe1367ce7b8ad542e489557..5a86ba2b934ac41d02a3796cd8f58bac20d61b62 100644 --- a/pgsql/tables/llx_adherent.sql +++ b/pgsql/tables/llx_adherent.sql @@ -1,63 +1,63 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== --- --- statut --- 0 : non adherent --- 1 : adherent - -create table llx_adherent -( - rowid SERIAL PRIMARY KEY, - "tms" timestamp, - "statut" smallint NOT NULL DEFAULT 0, - "public" smallint NOT NULL DEFAULT 0, -- certain champ de la fiche sont ils public ou pas ? - "fk_adherent_type" smallint, - "morphy" varchar(3) CHECK (morphy IN ('mor','phy')) NOT NULL, -- personne morale / personne physique - "datevalid" timestamp, -- date de validation - "datec" timestamp, -- date de creation - "prenom" varchar(50), - "nom" varchar(50), - "societe" varchar(50), - "adresse" text, - "cp" varchar(30), - "ville" varchar(50), - "pays" varchar(50), - "email" varchar(255), - "login" varchar(50) NOT NULL, -- login utilise pour editer sa fiche - "pass" varchar(50), -- pass utilise pour editer sa fiche - "naiss" date, -- date de naissance - "photo" varchar(255), -- url vers la photo de l'adherent - "fk_user_author" integer NOT NULL, - "fk_user_mod" integer NOT NULL, - "fk_user_valid" integer NOT NULL, - "datefin" timestamp, -- date de fin de validit� de la cotisation - "note" text, - - UNIQUE(login) -); - -CREATE INDEX idx_llx_adherent_login ON llx_adherent (login); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== +-- +-- statut +-- 0 : non adherent +-- 1 : adherent + +create table llx_adherent +( + rowid SERIAL PRIMARY KEY, + "tms" timestamp, + "statut" smallint NOT NULL DEFAULT 0, + "public" smallint NOT NULL DEFAULT 0, -- certain champ de la fiche sont ils public ou pas ? + "fk_adherent_type" smallint, + "morphy" varchar(3) CHECK (morphy IN ('mor','phy')) NOT NULL, -- personne morale / personne physique + "datevalid" timestamp, -- date de validation + "datec" timestamp, -- date de creation + "prenom" varchar(50), + "nom" varchar(50), + "societe" varchar(50), + "adresse" text, + "cp" varchar(30), + "ville" varchar(50), + "pays" varchar(50), + "email" varchar(255), + "login" varchar(50) NOT NULL, -- login utilise pour editer sa fiche + "pass" varchar(50), -- pass utilise pour editer sa fiche + "naiss" date, -- date de naissance + "photo" varchar(255), -- url vers la photo de l'adherent + "fk_user_author" integer NOT NULL, + "fk_user_mod" integer NOT NULL, + "fk_user_valid" integer NOT NULL, + "datefin" timestamp, -- date de fin de validit� de la cotisation + "note" text, + + UNIQUE(login) +); + +CREATE INDEX idx_llx_adherent_login ON llx_adherent (login); diff --git a/pgsql/tables/llx_adherent_options.sql b/pgsql/tables/llx_adherent_options.sql index 16401ff1dc109b48894e3525740a369445c71f93..fcc8e88ebebfe958424b84060b78dc625b180004 100644 --- a/pgsql/tables/llx_adherent_options.sql +++ b/pgsql/tables/llx_adherent_options.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - - -create table llx_adherent_options -( - optid SERIAL PRIMARY KEY, - "tms" timestamp, - "adhid" integer NOT NULL, -- id de l'adherent auquel correspond ces attributs optionnel - UNIQUE(adhid) -); - -CREATE INDEX idx_llx_adherent_options_adhid ON llx_adherent_options (adhid); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + + +create table llx_adherent_options +( + optid SERIAL PRIMARY KEY, + "tms" timestamp, + "adhid" integer NOT NULL, -- id de l'adherent auquel correspond ces attributs optionnel + UNIQUE(adhid) +); + +CREATE INDEX idx_llx_adherent_options_adhid ON llx_adherent_options (adhid); diff --git a/pgsql/tables/llx_adherent_options_label.sql b/pgsql/tables/llx_adherent_options_label.sql index fdb5b16b09be993b08fa433569b058c1d449cd0d..534ee7c9980e7f530802679c620b7b559e25c348 100644 --- a/pgsql/tables/llx_adherent_options_label.sql +++ b/pgsql/tables/llx_adherent_options_label.sql @@ -1,33 +1,33 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - -create table llx_adherent_options_label -( - name varchar(64) PRIMARY KEY, -- nom de l'attribut - "tms" timestamp, - "label" varchar(255) NOT NULL -- label correspondant a l'attribut -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + +create table llx_adherent_options_label +( + name varchar(64) PRIMARY KEY, -- nom de l'attribut + "tms" timestamp, + "label" varchar(255) NOT NULL -- label correspondant a l'attribut +); diff --git a/pgsql/tables/llx_adherent_type.sql b/pgsql/tables/llx_adherent_type.sql index c7d502c589dd4ca8e8eb1671ac4120b05d86ad30..343250332babc6b2f51b82ea7314f77539fe2f75 100644 --- a/pgsql/tables/llx_adherent_type.sql +++ b/pgsql/tables/llx_adherent_type.sql @@ -1,42 +1,42 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== --- --- statut --- 0 : actif --- 1 : inactif - -create table llx_adherent_type -( - rowid SERIAL PRIMARY KEY, - "tms" timestamp, - "statut" smallint NOT NULL DEFAULT 0, - "libelle" varchar(50), - "cotisation" varchar(3) CHECK (cotisation IN ('yes','no')) NOT NULL DEFAULT 'yes', - "vote" varchar(3) CHECK (vote IN ('yes','no')) NOT NULL DEFAULT 'yes', - "note" text, - "mail_valid" text -- mail envoye a la validation -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== +-- +-- statut +-- 0 : actif +-- 1 : inactif + +create table llx_adherent_type +( + rowid SERIAL PRIMARY KEY, + "tms" timestamp, + "statut" smallint NOT NULL DEFAULT 0, + "libelle" varchar(50), + "cotisation" varchar(3) CHECK (cotisation IN ('yes','no')) NOT NULL DEFAULT 'yes', + "vote" varchar(3) CHECK (vote IN ('yes','no')) NOT NULL DEFAULT 'yes', + "note" text, + "mail_valid" text -- mail envoye a la validation +); diff --git a/pgsql/tables/llx_appro.sql b/pgsql/tables/llx_appro.sql index 9d166328ec410eff4e5344b1f1ab4598b0682517..aa9cfe3f72c29c9a8d7a60eb411fee055ed4cbd2 100644 --- a/pgsql/tables/llx_appro.sql +++ b/pgsql/tables/llx_appro.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - -create table llx_appro -( - rowid SERIAL PRIMARY KEY, - "datec" timestamp, - "tms" timestamp, - "fk_product" integer NOT NULL, - "quantity" smallint NOT NULL, - "price" real, - "fk_user_author" integer -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + +create table llx_appro +( + rowid SERIAL PRIMARY KEY, + "datec" timestamp, + "tms" timestamp, + "fk_product" integer NOT NULL, + "quantity" smallint NOT NULL, + "price" real, + "fk_user_author" integer +); + diff --git a/pgsql/tables/llx_bank.sql b/pgsql/tables/llx_bank.sql index 879adfa5704d9d3b0fc9f100d42b943e9a603b70..e74ea90ab848129b3a621c3e6420ce25a7620481 100644 --- a/pgsql/tables/llx_bank.sql +++ b/pgsql/tables/llx_bank.sql @@ -1,47 +1,47 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2000-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - - - -create table llx_bank -( - rowid SERIAL PRIMARY KEY, - "datec" timestamp, - "datev" date, -- date de valeur - "dateo" date, -- date operation - "amount" real NOT NULL default 0, - "label" varchar(255), - "fk_account" integer, - "fk_user_author" integer, - "fk_user_rappro" integer, - "fk_type" varchar(4), -- CB, Virement, cheque - "num_releve" varchar(50), - "num_chq" int, - "rappro" smallint default 0, - "note" text, - "author" varchar(40) -- a supprimer apres migration -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2000-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + + + +create table llx_bank +( + rowid SERIAL PRIMARY KEY, + "datec" timestamp, + "datev" date, -- date de valeur + "dateo" date, -- date operation + "amount" real NOT NULL default 0, + "label" varchar(255), + "fk_account" integer, + "fk_user_author" integer, + "fk_user_rappro" integer, + "fk_type" varchar(4), -- CB, Virement, cheque + "num_releve" varchar(50), + "num_chq" int, + "rappro" smallint default 0, + "note" text, + "author" varchar(40) -- a supprimer apres migration +); diff --git a/pgsql/tables/llx_bank_account.key.sql b/pgsql/tables/llx_bank_account.key.sql index 3652d317e226c833a5eb85c2cf9c71d867b303ab..eee225dfa7e894a7effebbcf68d62ee0af540cb6 100644 --- a/pgsql/tables/llx_bank_account.key.sql +++ b/pgsql/tables/llx_bank_account.key.sql @@ -1,28 +1,28 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - - -ALTER TABLE llx_bank_account ADD UNIQUE uk_bank_account_label (label); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + + +ALTER TABLE llx_bank_account ADD UNIQUE uk_bank_account_label (label); diff --git a/pgsql/tables/llx_bank_account.sql b/pgsql/tables/llx_bank_account.sql index 7615ff257173061b67f27467b5a414a36086c9f9..6d686d7daf30802090989c8c4ccd58df4c56684e 100644 --- a/pgsql/tables/llx_bank_account.sql +++ b/pgsql/tables/llx_bank_account.sql @@ -1,54 +1,54 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================= --- Copyright (C) 2000-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004-2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- --- courant : type de compte: 0 epargne, 1 courant, 2 caisse --- clos : le compte est-il clos ou encore ouvert --- --- ============================================================================= - -create table llx_bank_account -( - rowid SERIAL PRIMARY KEY, - "datec" timestamp, - "tms" timestamp, - "ref" varchar(12) NOT NULL, - "label" varchar(30) NOT NULL, - "bank" varchar(60), - "code_banque" varchar(7), - "code_guichet" varchar(6), - "number" varchar(255), - "cle_rib" varchar(5), - "bic" varchar(10), - "iban_prefix" varchar(5), - "domiciliation" varchar(255), - "proprio" varchar(60), - "adresse_proprio" varchar(255), - "courant" smallint DEFAULT 0 NOT NULL, - "clos" smallint DEFAULT 0 NOT NULL, - "rappro" smallint DEFAULT 1, - "url" varchar(128), - "account_number" varchar(8) -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================= +-- Copyright (C) 2000-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004-2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- +-- courant : type de compte: 0 epargne, 1 courant, 2 caisse +-- clos : le compte est-il clos ou encore ouvert +-- +-- ============================================================================= + +create table llx_bank_account +( + rowid SERIAL PRIMARY KEY, + "datec" timestamp, + "tms" timestamp, + "ref" varchar(12) NOT NULL, + "label" varchar(30) NOT NULL, + "bank" varchar(60), + "code_banque" varchar(7), + "code_guichet" varchar(6), + "number" varchar(255), + "cle_rib" varchar(5), + "bic" varchar(10), + "iban_prefix" varchar(5), + "domiciliation" varchar(255), + "proprio" varchar(60), + "adresse_proprio" varchar(255), + "courant" smallint DEFAULT 0 NOT NULL, + "clos" smallint DEFAULT 0 NOT NULL, + "rappro" smallint DEFAULT 1, + "url" varchar(128), + "account_number" varchar(8) +); diff --git a/pgsql/tables/llx_bank_categ.sql b/pgsql/tables/llx_bank_categ.sql index ae82812d5bf7004c023868c79b1d0187216d5a87..1b60c922002bfc4a36b5d7cffb102ae86bc3b439 100644 --- a/pgsql/tables/llx_bank_categ.sql +++ b/pgsql/tables/llx_bank_categ.sql @@ -1,29 +1,29 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - -create table llx_bank_categ -( - rowid SERIAL PRIMARY KEY, - "label" varchar(255) -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + +create table llx_bank_categ +( + rowid SERIAL PRIMARY KEY, + "label" varchar(255) +); diff --git a/pgsql/tables/llx_bank_class.sql b/pgsql/tables/llx_bank_class.sql index 1a7c575e3d2a8c05bdad3b35ab1151cb02c36d5b..f4c725d0464023db7afa9927b756bd2f1d2697f1 100644 --- a/pgsql/tables/llx_bank_class.sql +++ b/pgsql/tables/llx_bank_class.sql @@ -1,32 +1,32 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - - -create table llx_bank_class -( - "lineid" integer NOT NULL, - "fk_categ" integer NOT NULL -); - -CREATE INDEX idx_llx_bank_class_lineid ON llx_bank_class (lineid); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + + +create table llx_bank_class +( + "lineid" integer NOT NULL, + "fk_categ" integer NOT NULL +); + +CREATE INDEX idx_llx_bank_class_lineid ON llx_bank_class (lineid); diff --git a/pgsql/tables/llx_bank_url.key.sql b/pgsql/tables/llx_bank_url.key.sql index c37e47031e0da81eb5b92e773442d1da14b726b2..47dbb06e0607a9a921c6c38cf631f13596fc61d9 100644 --- a/pgsql/tables/llx_bank_url.key.sql +++ b/pgsql/tables/llx_bank_url.key.sql @@ -1,28 +1,28 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + + ALTER TABLE llx_bank_url ADD UNIQUE uk_bank_url (fk_bank,url_id); \ No newline at end of file diff --git a/pgsql/tables/llx_bank_url.sql b/pgsql/tables/llx_bank_url.sql index dfe785c44632a74c1910f008870c6d638e425d62..00f6b058e057cb60919fc31731ae6d1041b842f6 100644 --- a/pgsql/tables/llx_bank_url.sql +++ b/pgsql/tables/llx_bank_url.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - -create table llx_bank_url -( - rowid SERIAL PRIMARY KEY, - "fk_bank" integer, - "url_id" integer, - "url" varchar(255), - "label" varchar(255), - "type" varchar(8) CHECK (type IN ('company','payment','member','donation','charge')) -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + +create table llx_bank_url +( + rowid SERIAL PRIMARY KEY, + "fk_bank" integer, + "url_id" integer, + "url" varchar(255), + "label" varchar(255), + "type" varchar(8) CHECK (type IN ('company','payment','member','donation','charge')) +); diff --git a/pgsql/tables/llx_bookmark.key.sql b/pgsql/tables/llx_bookmark.key.sql index 136f1e3cdaae92be141adb58429ccc305c748c1c..884cda006f148aaae6b90bbd6069afc06949dce9 100644 --- a/pgsql/tables/llx_bookmark.key.sql +++ b/pgsql/tables/llx_bookmark.key.sql @@ -1,29 +1,29 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - - -ALTER TABLE llx_bookmark ADD UNIQUE uk_bookmark_url (fk_user, url); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + + +ALTER TABLE llx_bookmark ADD UNIQUE uk_bookmark_url (fk_user, url); ALTER TABLE llx_bookmark ADD UNIQUE uk_bookmark_title (fk_user, title); \ No newline at end of file diff --git a/pgsql/tables/llx_bookmark.sql b/pgsql/tables/llx_bookmark.sql index 4cd397e6d5c7390ba6076a425e140e86a3bd489b..dba390fbb8716b1a0d35fdecd51eb7534ea6e2bb 100644 --- a/pgsql/tables/llx_bookmark.sql +++ b/pgsql/tables/llx_bookmark.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - -create table llx_bookmark -( - rowid SERIAL PRIMARY KEY, - "fk_soc" integer, - "fk_user" integer NOT NULL, - "dateb" timestamp, - "url" varchar(128) NOT NULL, - "target" varchar(16), - "title" varchar(64), - "favicon" varchar(24) -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + +create table llx_bookmark +( + rowid SERIAL PRIMARY KEY, + "fk_soc" integer, + "fk_user" integer NOT NULL, + "dateb" timestamp, + "url" varchar(128) NOT NULL, + "target" varchar(16), + "title" varchar(64), + "favicon" varchar(24) +); diff --git a/pgsql/tables/llx_bookmark4u_login.sql b/pgsql/tables/llx_bookmark4u_login.sql index ad67ec77eccbf92c69d74842b81c0953c4035609..3487873aa642e79c0f3952c12fc7d13174b5235e 100644 --- a/pgsql/tables/llx_bookmark4u_login.sql +++ b/pgsql/tables/llx_bookmark4u_login.sql @@ -1,36 +1,36 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =========================================================================== - - -create table llx_bookmark4u_login -( - rowid SERIAL PRIMARY KEY, - "fk_user" integer, - "bk4u_uid" integer, - UNIQUE(fk_user) -); - -CREATE INDEX idx_llx_bookmark4u_login_fk_user ON llx_bookmark4u_login (fk_user); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =========================================================================== + + +create table llx_bookmark4u_login +( + rowid SERIAL PRIMARY KEY, + "fk_user" integer, + "bk4u_uid" integer, + UNIQUE(fk_user) +); + +CREATE INDEX idx_llx_bookmark4u_login_fk_user ON llx_bookmark4u_login (fk_user); diff --git a/pgsql/tables/llx_boxes.sql b/pgsql/tables/llx_boxes.sql index 684004881f034a4dcb445cbabc8592a54a9ff4ca..c5a539ba8b88a118a1d3cdeecf95fe9bcfbb3def 100644 --- a/pgsql/tables/llx_boxes.sql +++ b/pgsql/tables/llx_boxes.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =========================================================================== --- --- position : 0-index.php, 1-left, 2-right --- --- - -create table llx_boxes -( - rowid SERIAL PRIMARY KEY, - "box_id" integer NOT NULL, - "position" smallint NOT NULL, - "box_order" smallint default 0 NOT NULL -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =========================================================================== +-- +-- position : 0-index.php, 1-left, 2-right +-- +-- + +create table llx_boxes +( + rowid SERIAL PRIMARY KEY, + "box_id" integer NOT NULL, + "position" smallint NOT NULL, + "box_order" smallint default 0 NOT NULL +); diff --git a/pgsql/tables/llx_boxes_def.sql b/pgsql/tables/llx_boxes_def.sql index 0e048dd9e3d0b1ae6efb31b11a1162250d1ee34c..b98e25043832e968d29f734fce8c6f175a246c0f 100644 --- a/pgsql/tables/llx_boxes_def.sql +++ b/pgsql/tables/llx_boxes_def.sql @@ -1,33 +1,33 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =========================================================================== - -create table llx_boxes_def -( - rowid SERIAL PRIMARY KEY, - "name" varchar(255) NOT NULL, - "file" varchar(255) NOT NULL, - "note" text -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =========================================================================== + +create table llx_boxes_def +( + rowid SERIAL PRIMARY KEY, + "name" varchar(255) NOT NULL, + "file" varchar(255) NOT NULL, + "note" text +); diff --git a/pgsql/tables/llx_c_actioncomm.sql b/pgsql/tables/llx_c_actioncomm.sql index 70375996285472bc52dfa3f11f663fc193394975..500906e87885f1c4c6bf0e77871ba64bee8734d6 100644 --- a/pgsql/tables/llx_c_actioncomm.sql +++ b/pgsql/tables/llx_c_actioncomm.sql @@ -1,36 +1,36 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_actioncomm -( - id integer PRIMARY KEY, - "code" varchar(12) UNIQUE NOT NULL, - "type" varchar(10) DEFAULT 'system' NOT NULL, - "libelle" varchar(30) NOT NULL, - "active" smallint DEFAULT 1 NOT NULL, - "todo" smallint -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_actioncomm +( + id integer PRIMARY KEY, + "code" varchar(12) UNIQUE NOT NULL, + "type" varchar(10) DEFAULT 'system' NOT NULL, + "libelle" varchar(30) NOT NULL, + "active" smallint DEFAULT 1 NOT NULL, + "todo" smallint +); diff --git a/pgsql/tables/llx_c_ape.sql b/pgsql/tables/llx_c_ape.sql index abca17e00edac4a873e905dc4924f36b6c893d25..919d0d1596de1d9e2a7bd40206407b4c1ff3d90e 100644 --- a/pgsql/tables/llx_c_ape.sql +++ b/pgsql/tables/llx_c_ape.sql @@ -1,39 +1,39 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - - -create table llx_c_ape -( - rowid SERIAL PRIMARY KEY, - "code_ape" varchar(5) NOT NULL, - "libelle" varchar(255), - "active" smallint DEFAULT 1 NOT NULL, - UNIQUE(code_ape) -); - -CREATE INDEX idx_llx_c_ape_code_ape ON llx_c_ape (code_ape); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + + +create table llx_c_ape +( + rowid SERIAL PRIMARY KEY, + "code_ape" varchar(5) NOT NULL, + "libelle" varchar(255), + "active" smallint DEFAULT 1 NOT NULL, + UNIQUE(code_ape) +); + +CREATE INDEX idx_llx_c_ape_code_ape ON llx_c_ape (code_ape); + diff --git a/pgsql/tables/llx_c_chargesociales.sql b/pgsql/tables/llx_c_chargesociales.sql index d0b29f8d61564928ea45d61afcffea6f4ccb9697..cf7ba95b8ebdd1bc3282b1c25d4b3b084db6c25d 100644 --- a/pgsql/tables/llx_c_chargesociales.sql +++ b/pgsql/tables/llx_c_chargesociales.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ======================================================================== - -create table llx_c_chargesociales -( - id SERIAL PRIMARY KEY, - "libelle" varchar(80), - "deductible" smallint DEFAULT 0 NOT NULL, - "active" smallint DEFAULT 1 NOT NULL -); - - - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ======================================================================== + +create table llx_c_chargesociales +( + id SERIAL PRIMARY KEY, + "libelle" varchar(80), + "deductible" smallint DEFAULT 0 NOT NULL, + "active" smallint DEFAULT 1 NOT NULL +); + + + diff --git a/pgsql/tables/llx_c_civilite.sql b/pgsql/tables/llx_c_civilite.sql index 1d39bec2155bf15908712fd3e951f871458a4178..fb1083c90d640605a82c64c53dbbfa4642574114 100644 --- a/pgsql/tables/llx_c_civilite.sql +++ b/pgsql/tables/llx_c_civilite.sql @@ -1,34 +1,34 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- ======================================================================== - -create table llx_c_civilite -( - rowid integer PRIMARY KEY, - "code" varchar(6) UNIQUE NOT NULL, - "civilite" varchar(50), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- ======================================================================== + +create table llx_c_civilite +( + rowid integer PRIMARY KEY, + "code" varchar(6) UNIQUE NOT NULL, + "civilite" varchar(50), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_currencies.key.sql b/pgsql/tables/llx_c_currencies.key.sql index 2c7b36ec8b90c889fece35863ab780c19fd1ee4b..c89b9f82a6b9807355413d22b3bc0a96432a879b 100644 --- a/pgsql/tables/llx_c_currencies.key.sql +++ b/pgsql/tables/llx_c_currencies.key.sql @@ -1,28 +1,28 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - - -ALTER TABLE llx_c_currencies ADD UNIQUE uk_c_currencies_code_iso(code_iso); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + + +ALTER TABLE llx_c_currencies ADD UNIQUE uk_c_currencies_code_iso(code_iso); diff --git a/pgsql/tables/llx_c_currencies.sql b/pgsql/tables/llx_c_currencies.sql index 0cbf4e87877a30d679841e2670fb8469f68866a3..2f04766d58dba840b0fd77198851ce831f31eedf 100644 --- a/pgsql/tables/llx_c_currencies.sql +++ b/pgsql/tables/llx_c_currencies.sql @@ -1,34 +1,34 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_currencies -( - code varchar(2) PRIMARY KEY, - "code_iso" varchar(3) NOT NULL, - "label" varchar(64), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_currencies +( + code varchar(2) PRIMARY KEY, + "code_iso" varchar(3) NOT NULL, + "label" varchar(64), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_departements.key.sql b/pgsql/tables/llx_c_departements.key.sql index ff19bcefe7d747373ee7c0d5eb5c58ba2bf199ea..21977b2f6e4af352866b75b187354bf5adb2271e 100644 --- a/pgsql/tables/llx_c_departements.key.sql +++ b/pgsql/tables/llx_c_departements.key.sql @@ -1,31 +1,31 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - - -ALTER TABLE llx_c_departements ADD UNIQUE uk_departements (code_departement,fk_region); - - -ALTER TABLE llx_c_departements ADD INDEX idx_departements_fk_region (fk_region); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + + +ALTER TABLE llx_c_departements ADD UNIQUE uk_departements (code_departement,fk_region); + + +ALTER TABLE llx_c_departements ADD INDEX idx_departements_fk_region (fk_region); diff --git a/pgsql/tables/llx_c_departements.sql b/pgsql/tables/llx_c_departements.sql index 9821327a93bf051ba298d8440282d9604e034a23..05697f7ec73a9ddb99b515697671ab250905d017 100644 --- a/pgsql/tables/llx_c_departements.sql +++ b/pgsql/tables/llx_c_departements.sql @@ -1,41 +1,41 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_departements -( - rowid SERIAL PRIMARY KEY, - "code_departement" varchar(6) NOT NULL, - "fk_region" integer, - "cheflieu" varchar(7), - "tncc" integer, - "ncc" varchar(50), - "nom" varchar(50), - "active" smallint DEFAULT 1 NOT NULL -); - - - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_departements +( + rowid SERIAL PRIMARY KEY, + "code_departement" varchar(6) NOT NULL, + "fk_region" integer, + "cheflieu" varchar(7), + "tncc" integer, + "ncc" varchar(50), + "nom" varchar(50), + "active" smallint DEFAULT 1 NOT NULL +); + + + diff --git a/pgsql/tables/llx_c_effectif.sql b/pgsql/tables/llx_c_effectif.sql index ea84189e766c8343aff8203eb96228aee1a7b560..16dd84d1ebdcf31e88032b1e7e8169607dda77d5 100644 --- a/pgsql/tables/llx_c_effectif.sql +++ b/pgsql/tables/llx_c_effectif.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_effectif -( - id integer PRIMARY KEY, - "code" varchar(12) UNIQUE NOT NULL, - "libelle" varchar(30), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_effectif +( + id integer PRIMARY KEY, + "code" varchar(12) UNIQUE NOT NULL, + "libelle" varchar(30), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_forme_juridique.sql b/pgsql/tables/llx_c_forme_juridique.sql index 489240a6f2207275217f862b2dee16c04dd7a1fd..707e1c75d7aa35d73ea25326610108ed64e7a0fc 100644 --- a/pgsql/tables/llx_c_forme_juridique.sql +++ b/pgsql/tables/llx_c_forme_juridique.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ======================================================================== - - -create table llx_c_forme_juridique -( - rowid SERIAL PRIMARY KEY, - "code" varchar(12) UNIQUE NOT NULL, - "fk_pays" integer NOT NULL, - "libelle" varchar(255), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ======================================================================== + + +create table llx_c_forme_juridique +( + rowid SERIAL PRIMARY KEY, + "code" varchar(12) UNIQUE NOT NULL, + "fk_pays" integer NOT NULL, + "libelle" varchar(255), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_methode_commande_fournisseur.sql b/pgsql/tables/llx_c_methode_commande_fournisseur.sql index d41af24eda4a56fbe5dd55366d95e70f449d4016..6c5470f874e179859812e03282dc10daad08df0a 100644 --- a/pgsql/tables/llx_c_methode_commande_fournisseur.sql +++ b/pgsql/tables/llx_c_methode_commande_fournisseur.sql @@ -1,39 +1,39 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - - -create table llx_c_methode_commande_fournisseur -( - rowid SERIAL PRIMARY KEY, - "code" varchar(30), - "libelle" varchar(60), - "active" smallint default 1 NOT NULL, - UNIQUE(code) -); - -CREATE INDEX idx_llx_c_methode_commande_fournisseur_code ON llx_c_methode_commande_fournisseur (code); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + + +create table llx_c_methode_commande_fournisseur +( + rowid SERIAL PRIMARY KEY, + "code" varchar(30), + "libelle" varchar(60), + "active" smallint default 1 NOT NULL, + UNIQUE(code) +); + +CREATE INDEX idx_llx_c_methode_commande_fournisseur_code ON llx_c_methode_commande_fournisseur (code); + diff --git a/pgsql/tables/llx_c_paiement.sql b/pgsql/tables/llx_c_paiement.sql index 31f7674d2476f9106545a684609daeec8e987036..2d741dd8aebe5dba8a5fb68adc342f7a37b50fc2 100644 --- a/pgsql/tables/llx_c_paiement.sql +++ b/pgsql/tables/llx_c_paiement.sql @@ -1,44 +1,44 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ======================================================================== --- --- Type : --- --- 0 : entr�e d'argent --- 1 : sortie d'argent --- 2 : entr�e ou sortie d'argent - -create table llx_c_paiement -( - id integer PRIMARY KEY, - "code" varchar(6) UNIQUE NOT NULL, - "libelle" varchar(30), - "type" smallint, - "active" smallint DEFAULT 1 NOT NULL -); - - - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ======================================================================== +-- +-- Type : +-- +-- 0 : entr�e d'argent +-- 1 : sortie d'argent +-- 2 : entr�e ou sortie d'argent + +create table llx_c_paiement +( + id integer PRIMARY KEY, + "code" varchar(6) UNIQUE NOT NULL, + "libelle" varchar(30), + "type" smallint, + "active" smallint DEFAULT 1 NOT NULL +); + + + diff --git a/pgsql/tables/llx_c_pays.key.sql b/pgsql/tables/llx_c_pays.key.sql index 45ec508c3f05e3cee3358823ce9deac9648ab824..2682ab572a248cfb0e079da94bd74ec74004373b 100644 --- a/pgsql/tables/llx_c_pays.key.sql +++ b/pgsql/tables/llx_c_pays.key.sql @@ -1,30 +1,30 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - - -ALTER TABLE llx_c_pays ADD UNIQUE INDEX idx_c_pays_code (code); -ALTER TABLE llx_c_pays ADD UNIQUE INDEX idx_c_pays_code_iso (code_iso); -ALTER TABLE llx_c_pays ADD UNIQUE INDEX idx_c_pays_libelle (libelle); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + + +ALTER TABLE llx_c_pays ADD UNIQUE INDEX idx_c_pays_code (code); +ALTER TABLE llx_c_pays ADD UNIQUE INDEX idx_c_pays_code_iso (code_iso); +ALTER TABLE llx_c_pays ADD UNIQUE INDEX idx_c_pays_libelle (libelle); diff --git a/pgsql/tables/llx_c_pays.sql b/pgsql/tables/llx_c_pays.sql index 77e90a3169de5244b6c0b83e09d18f5f17063ab0..94889fb7cab3e0b8391117079cf86534133d1af5 100644 --- a/pgsql/tables/llx_c_pays.sql +++ b/pgsql/tables/llx_c_pays.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_pays -( - rowid integer PRIMARY KEY, - "code" varchar(2) NOT NULL, - "code_iso" varchar(3) , - "libelle" varchar(50) NOT NULL, - "active" smallint DEFAULT 1 NOT NULL -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_pays +( + rowid integer PRIMARY KEY, + "code" varchar(2) NOT NULL, + "code_iso" varchar(3) , + "libelle" varchar(50) NOT NULL, + "active" smallint DEFAULT 1 NOT NULL +); diff --git a/pgsql/tables/llx_c_propalst.sql b/pgsql/tables/llx_c_propalst.sql index 3a61a3d6024c94b2abb0321ffa607ef841578556..4f325b77cf5f7d2e9e8fda12aa911c62132ceb5e 100644 --- a/pgsql/tables/llx_c_propalst.sql +++ b/pgsql/tables/llx_c_propalst.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - -create table llx_c_propalst -( - id smallint PRIMARY KEY, - "code" varchar(12) UNIQUE NOT NULL, - "label" varchar(30), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + +create table llx_c_propalst +( + id smallint PRIMARY KEY, + "code" varchar(12) UNIQUE NOT NULL, + "label" varchar(30), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_regions.key.sql b/pgsql/tables/llx_c_regions.key.sql index 6ae53fb21638ba9c693666420dec92b14c564c4d..edc91a35f7d0716bf543f03502faec4a117d5e25 100644 --- a/pgsql/tables/llx_c_regions.key.sql +++ b/pgsql/tables/llx_c_regions.key.sql @@ -1,29 +1,29 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - - -ALTER TABLE llx_c_regions ADD INDEX idx_c_regions_fk_pays (fk_pays); -ALTER TABLE llx_c_regions ADD CONSTRAINT fk_c_regions_fk_pays FOREIGN KEY (fk_pays) REFERENCES llx_c_pays (rowid); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + + +ALTER TABLE llx_c_regions ADD INDEX idx_c_regions_fk_pays (fk_pays); +ALTER TABLE llx_c_regions ADD CONSTRAINT fk_c_regions_fk_pays FOREIGN KEY (fk_pays) REFERENCES llx_c_pays (rowid); diff --git a/pgsql/tables/llx_c_regions.sql b/pgsql/tables/llx_c_regions.sql index d99dd3bb9dd84db4a6477b6536a72f31b6e94457..9edaa4da125798a8172580d9465fbdafe20d6f72 100644 --- a/pgsql/tables/llx_c_regions.sql +++ b/pgsql/tables/llx_c_regions.sql @@ -1,38 +1,38 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_regions -( - rowid SERIAL PRIMARY KEY, - "code_region" integer UNIQUE NOT NULL, - "fk_pays" integer NOT NULL, - "cheflieu" varchar(7), - "tncc" integer, - "nom" varchar(50), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_regions +( + rowid SERIAL PRIMARY KEY, + "code_region" integer UNIQUE NOT NULL, + "fk_pays" integer NOT NULL, + "cheflieu" varchar(7), + "tncc" integer, + "nom" varchar(50), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_stcomm.sql b/pgsql/tables/llx_c_stcomm.sql index 6148d9c97490e29e849c2aebeb7069798180c72a..22caa785033b9c3eed82cf5757b2dee6bbde21dd 100644 --- a/pgsql/tables/llx_c_stcomm.sql +++ b/pgsql/tables/llx_c_stcomm.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - -create table llx_c_stcomm -( - id integer PRIMARY KEY, - "code" varchar(12) UNIQUE NOT NULL, - "libelle" varchar(30), - "active" smallint default 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + +create table llx_c_stcomm +( + id integer PRIMARY KEY, + "code" varchar(12) UNIQUE NOT NULL, + "libelle" varchar(30), + "active" smallint default 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_tva.sql b/pgsql/tables/llx_c_tva.sql index b52ed3a874afbcc21f9dda00cb58e6ed8c4ef44b..a3eff5ef3a2bebc5e586ae67b523c1c207e581bb 100644 --- a/pgsql/tables/llx_c_tva.sql +++ b/pgsql/tables/llx_c_tva.sql @@ -1,37 +1,37 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ======================================================================== - - -create table llx_c_tva -( - rowid SERIAL PRIMARY KEY, - "fk_pays" integer NOT NULL, - "taux" real NOT NULL, - "recuperableonly" integer NOT NULL DEFAULT 0, - "note" varchar(128), - "active" smallint DEFAULT 1 NOT NULL -); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ======================================================================== + + +create table llx_c_tva +( + rowid SERIAL PRIMARY KEY, + "fk_pays" integer NOT NULL, + "taux" real NOT NULL, + "recuperableonly" integer NOT NULL DEFAULT 0, + "note" varchar(128), + "active" smallint DEFAULT 1 NOT NULL +); + diff --git a/pgsql/tables/llx_c_type_contact.key.sql b/pgsql/tables/llx_c_type_contact.key.sql index fbeefa530771bdacb157454d277bc3d82fd77caa..8cebdee3acb76165ae87c4dceb7e5f1c66587dfa 100644 --- a/pgsql/tables/llx_c_type_contact.key.sql +++ b/pgsql/tables/llx_c_type_contact.key.sql @@ -1,39 +1,39 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Patrick Rouillon <patrick.rouillon.net> --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- Defini les types de contact d'un element sert de reference pour --- la table llx_element_contact --- --- element est le nom de la table utilisant le type de contact. --- i.e. contact, facture, projet, societe (sans le llx_ devant). --- Libelle est un texte d�crivant le type de contact. --- active pr�cide si cette valeur est active ou 'archiv�'. --- --- ======================================================================== - - -ALTER TABLE llx_c_type_contact - ADD UNIQUE INDEX idx_c_type_contact_uk (element, source, code); - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Patrick Rouillon <patrick.rouillon.net> +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- Defini les types de contact d'un element sert de reference pour +-- la table llx_element_contact +-- +-- element est le nom de la table utilisant le type de contact. +-- i.e. contact, facture, projet, societe (sans le llx_ devant). +-- Libelle est un texte d�crivant le type de contact. +-- active pr�cide si cette valeur est active ou 'archiv�'. +-- +-- ======================================================================== + + +ALTER TABLE llx_c_type_contact + ADD UNIQUE INDEX idx_c_type_contact_uk (element, source, code); + diff --git a/pgsql/tables/llx_c_type_contact.sql b/pgsql/tables/llx_c_type_contact.sql index bb54146b7c647378308e7752545b29d0abdf0a6b..d08430097927b9a116f9ac4c1055721f70cc91a3 100644 --- a/pgsql/tables/llx_c_type_contact.sql +++ b/pgsql/tables/llx_c_type_contact.sql @@ -1,45 +1,45 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2005 Patrick Rouillon <patrick.rouillon.net> --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- Defini les types de contact d'un element sert de reference pour --- la table llx_element_contact --- --- element est le nom de la table utilisant le type de contact. --- i.e. contact, facture, projet, societe (sans le llx_ devant). --- Libelle est un texte d�crivant le type de contact. --- active pr�cide si cette valeur est active ou 'archiv�'. --- --- ======================================================================== - - -create table llx_c_type_contact -( - rowid integer PRIMARY KEY, - "element" varchar(30) NOT NULL, - "source" varchar(8) DEFAULT 'external' NOT NULL, - "code" varchar(16) NOT NULL, - "libelle" varchar(64) NOT NULL, - "active" smallint DEFAULT 1 NOT NULL -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2005 Patrick Rouillon <patrick.rouillon.net> +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- Defini les types de contact d'un element sert de reference pour +-- la table llx_element_contact +-- +-- element est le nom de la table utilisant le type de contact. +-- i.e. contact, facture, projet, societe (sans le llx_ devant). +-- Libelle est un texte d�crivant le type de contact. +-- active pr�cide si cette valeur est active ou 'archiv�'. +-- +-- ======================================================================== + + +create table llx_c_type_contact +( + rowid integer PRIMARY KEY, + "element" varchar(30) NOT NULL, + "source" varchar(8) DEFAULT 'external' NOT NULL, + "code" varchar(16) NOT NULL, + "libelle" varchar(64) NOT NULL, + "active" smallint DEFAULT 1 NOT NULL +); diff --git a/pgsql/tables/llx_c_typent.sql b/pgsql/tables/llx_c_typent.sql index ed7289cc20b66c4c7179d0fa6f62e28ff78caed2..445f2589cd1312a9e179c15a4696e77be538632b 100644 --- a/pgsql/tables/llx_c_typent.sql +++ b/pgsql/tables/llx_c_typent.sql @@ -1,34 +1,34 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ======================================================================== - -create table llx_c_typent -( - id integer PRIMARY KEY, - "code" varchar(12) UNIQUE NOT NULL, - "libelle" varchar(30), - "active" smallint DEFAULT 1 NOT NULL -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ======================================================================== + +create table llx_c_typent +( + id integer PRIMARY KEY, + "code" varchar(12) UNIQUE NOT NULL, + "libelle" varchar(30), + "active" smallint DEFAULT 1 NOT NULL +); diff --git a/pgsql/tables/llx_categorie.sql b/pgsql/tables/llx_categorie.sql index 99011a28598fefaf0e433f7a15b9b4ee5ad00288..b9ee50bb4e284c978077da7fa7002804a7610418 100644 --- a/pgsql/tables/llx_categorie.sql +++ b/pgsql/tables/llx_categorie.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2005 Brice Davoleau <e1davole@iu-vannes.fr> --- Copyright (C) 2005 Matthieu Valleton <mv@seeschloss.org> --- Copyright (C) 2005-2006 Regis Houssin <regis.houssin@cap-networks.com> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - -create table llx_categorie -( - rowid SERIAL PRIMARY KEY, - "label" VARCHAR(255), -- nom de la cat�gorie - "description" text, -- description de la cat�gorie - "visible" smallint DEFAULT 1 NOT NULL -- determine si les produits sont visible ou pas -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2005 Brice Davoleau <e1davole@iu-vannes.fr> +-- Copyright (C) 2005 Matthieu Valleton <mv@seeschloss.org> +-- Copyright (C) 2005-2006 Regis Houssin <regis.houssin@cap-networks.com> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + +create table llx_categorie +( + rowid SERIAL PRIMARY KEY, + "label" VARCHAR(255), -- nom de la cat�gorie + "description" text, -- description de la cat�gorie + "visible" smallint DEFAULT 1 NOT NULL -- determine si les produits sont visible ou pas +); diff --git a/pgsql/tables/llx_categorie_product.key.sql b/pgsql/tables/llx_categorie_product.key.sql index fa83f2d609640c019c3f051a375d4a96b8068fe7..8807c987fd8da5154e5e0ef0f9c3c64146a1ada6 100644 --- a/pgsql/tables/llx_categorie_product.key.sql +++ b/pgsql/tables/llx_categorie_product.key.sql @@ -1,31 +1,31 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2005 Brice Davoleau <e1davole@iu-vannes.fr> --- Copyright (C) 2005 Matthieu Valleton <mv@seeschloss.org> --- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- ============================================================================ - - -ALTER TABLE llx_categorie_product ADD INDEX idx_categorie_product_fk_categorie (fk_categorie); -ALTER TABLE llx_categorie_product ADD INDEX idx_categorie_product_fk_product (fk_product); - -ALTER TABLE llx_categorie_product ADD FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); -ALTER TABLE llx_categorie_product ADD FOREIGN KEY (fk_product) REFERENCES llx_product (rowid); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2005 Brice Davoleau <e1davole@iu-vannes.fr> +-- Copyright (C) 2005 Matthieu Valleton <mv@seeschloss.org> +-- Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- ============================================================================ + + +ALTER TABLE llx_categorie_product ADD INDEX idx_categorie_product_fk_categorie (fk_categorie); +ALTER TABLE llx_categorie_product ADD INDEX idx_categorie_product_fk_product (fk_product); + +ALTER TABLE llx_categorie_product ADD FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); +ALTER TABLE llx_categorie_product ADD FOREIGN KEY (fk_product) REFERENCES llx_product (rowid); diff --git a/pgsql/tables/llx_chargesociales.sql b/pgsql/tables/llx_chargesociales.sql index db0f52f8852ddff3f194c44628ecc0ebe7bb3eab..b098d057f41f94ca8fa5517a14417b98f3097112 100644 --- a/pgsql/tables/llx_chargesociales.sql +++ b/pgsql/tables/llx_chargesociales.sql @@ -1,40 +1,40 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ======================================================================== --- Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ======================================================================== - -create table llx_chargesociales -( - rowid SERIAL PRIMARY KEY, - "date_ech" timestamp, -- date d'echeance - "date_pai" timestamp, -- date de paiements - "libelle" varchar(80), - "fk_type" integer, - "amount" real default 0 NOT NULL, - "paye" smallint default 0 NOT NULL, - "periode" date -); - - - +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ======================================================================== +-- Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ======================================================================== + +create table llx_chargesociales +( + rowid SERIAL PRIMARY KEY, + "date_ech" timestamp, -- date d'echeance + "date_pai" timestamp, -- date de paiements + "libelle" varchar(80), + "fk_type" integer, + "amount" real default 0 NOT NULL, + "paye" smallint default 0 NOT NULL, + "periode" date +); + + + diff --git a/pgsql/tables/llx_co_fa.sql b/pgsql/tables/llx_co_fa.sql index bf081315f6a0046d8f629264c4cfbd677c29c360..d41490632d13f77584de8fc6b1a436fc6db8e655 100644 --- a/pgsql/tables/llx_co_fa.sql +++ b/pgsql/tables/llx_co_fa.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- =================================================================== - - -create table llx_co_fa -( - rowid SERIAL PRIMARY KEY, - "fk_commande" integer NOT NULL, - "fk_facture" integer NOT NULL -); - -CREATE INDEX idx_llx_co_fa_fk_commande ON llx_co_fa (fk_commande); -CREATE INDEX idx_llx_co_fa_fk_facture ON llx_co_fa (fk_facture); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- =================================================================== + + +create table llx_co_fa +( + rowid SERIAL PRIMARY KEY, + "fk_commande" integer NOT NULL, + "fk_facture" integer NOT NULL +); + +CREATE INDEX idx_llx_co_fa_fk_commande ON llx_co_fa (fk_commande); +CREATE INDEX idx_llx_co_fa_fk_facture ON llx_co_fa (fk_facture); diff --git a/pgsql/tables/llx_co_pr.sql b/pgsql/tables/llx_co_pr.sql index c65e1826e6feda53b074e130b71fa0e033930393..e7ebfbc928ffbeced558e8cee347416153225992 100644 --- a/pgsql/tables/llx_co_pr.sql +++ b/pgsql/tables/llx_co_pr.sql @@ -1,31 +1,31 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- =================================================================== - -create table llx_co_pr -( - rowid SERIAL PRIMARY KEY, - "fk_commande" integer, - "fk_propale" integer -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- =================================================================== + +create table llx_co_pr +( + rowid SERIAL PRIMARY KEY, + "fk_commande" integer, + "fk_propale" integer +); diff --git a/pgsql/tables/llx_comfourn_facfourn.sql b/pgsql/tables/llx_comfourn_facfourn.sql index e0ee1ff43dfd5cab7be061d03d6f2cf82eb3961b..0b4025c5481f20e7dbc588f184507b265d5f6d82 100644 --- a/pgsql/tables/llx_comfourn_facfourn.sql +++ b/pgsql/tables/llx_comfourn_facfourn.sql @@ -1,36 +1,36 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2005-2006 Regis Houssin <regis.houssin@cap-networks.com> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- =================================================================== - - -create table llx_comfourn_facfourn -( - rowid SERIAL PRIMARY KEY, - "fk_commande" integer NOT NULL, - "fk_facture" integer NOT NULL -); - -CREATE INDEX idx_llx_comfourn_facfourn_fk_commande ON llx_comfourn_facfourn (fk_commande); -CREATE INDEX idx_llx_comfourn_facfourn_fk_facture ON llx_comfourn_facfourn (fk_facture); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2005-2006 Regis Houssin <regis.houssin@cap-networks.com> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- =================================================================== + + +create table llx_comfourn_facfourn +( + rowid SERIAL PRIMARY KEY, + "fk_commande" integer NOT NULL, + "fk_facture" integer NOT NULL +); + +CREATE INDEX idx_llx_comfourn_facfourn_fk_commande ON llx_comfourn_facfourn (fk_commande); +CREATE INDEX idx_llx_comfourn_facfourn_fk_facture ON llx_comfourn_facfourn (fk_facture); diff --git a/pgsql/tables/llx_commande.key.sql b/pgsql/tables/llx_commande.key.sql index 970a7a3d2078d9bf12d0b05154c7dc4c62f245cf..6854907c825d74c60ec1fa26d60ac5b92039b9a5 100644 --- a/pgsql/tables/llx_commande.key.sql +++ b/pgsql/tables/llx_commande.key.sql @@ -1,32 +1,32 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - - --- Supprimme orphelins pour permettre mont�e de la cl� --- V4 DELETE llx_commande FROM llx_commande LEFT JOIN llx_societe ON llx_commande.fk_soc = llx_societe.idp WHERE llx_societe.idp IS NULL; - -ALTER TABLE llx_commande ADD INDEX idx_commande_fk_soc (fk_soc); -ALTER TABLE llx_commande ADD CONSTRAINT fk_commande_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + + +-- Supprimme orphelins pour permettre mont�e de la cl� +-- V4 DELETE llx_commande FROM llx_commande LEFT JOIN llx_societe ON llx_commande.fk_soc = llx_societe.idp WHERE llx_societe.idp IS NULL; + +ALTER TABLE llx_commande ADD INDEX idx_commande_fk_soc (fk_soc); +ALTER TABLE llx_commande ADD CONSTRAINT fk_commande_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); diff --git a/pgsql/tables/llx_commande.sql b/pgsql/tables/llx_commande.sql index bf62edc0624db7afd6a193907a624335430a8c44..618caee44f1a6df0f1c78f7a65c4bd4b6c6078f5 100644 --- a/pgsql/tables/llx_commande.sql +++ b/pgsql/tables/llx_commande.sql @@ -1,65 +1,65 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - - - - -create table llx_commande -( - rowid SERIAL PRIMARY KEY, - "tms" timestamp, - "fk_soc" integer NOT NULL, - "fk_projet" integer DEFAULT 0, -- projet auquel est rattache la commande - "ref" varchar(30) NOT NULL, -- order number - "ref_client" varchar(30), -- customer order number - "date_creation" timestamp, -- date de creation - "date_valid" timestamp, -- date de validation - "date_cloture" timestamp, -- date de cloture - "date_commande" date, -- date de la commande - "fk_user_author" integer, -- createur de la commande - "fk_user_valid" integer, -- valideur de la commande - "fk_user_cloture" integer, -- auteur cloture - "source" smallint NOT NULL, - "fk_statut" smallint default 0, - "amount_ht" real default 0, - "remise_percent" real default 0, - "remise_absolue" real default 0, - "remise" real default 0, - "tva" real default 0, - "total_ht" real default 0, - "total_ttc" real default 0, - "note" text, - "note_public" text, - "model_pdf" varchar(50), - "facture" smallint default 0, - "fk_cond_reglement" integer, -- condition de r�glement - "fk_mode_reglement" integer, -- mode de r�glement - "date_livraison" date default NULL, - "fk_adresse_livraison" integer, -- adresse de livraison - UNIQUE(ref) -); - -CREATE INDEX idx_llx_commande_ref ON llx_commande (ref); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + + + + +create table llx_commande +( + rowid SERIAL PRIMARY KEY, + "tms" timestamp, + "fk_soc" integer NOT NULL, + "fk_projet" integer DEFAULT 0, -- projet auquel est rattache la commande + "ref" varchar(30) NOT NULL, -- order number + "ref_client" varchar(30), -- customer order number + "date_creation" timestamp, -- date de creation + "date_valid" timestamp, -- date de validation + "date_cloture" timestamp, -- date de cloture + "date_commande" date, -- date de la commande + "fk_user_author" integer, -- createur de la commande + "fk_user_valid" integer, -- valideur de la commande + "fk_user_cloture" integer, -- auteur cloture + "source" smallint NOT NULL, + "fk_statut" smallint default 0, + "amount_ht" real default 0, + "remise_percent" real default 0, + "remise_absolue" real default 0, + "remise" real default 0, + "tva" real default 0, + "total_ht" real default 0, + "total_ttc" real default 0, + "note" text, + "note_public" text, + "model_pdf" varchar(50), + "facture" smallint default 0, + "fk_cond_reglement" integer, -- condition de r�glement + "fk_mode_reglement" integer, -- mode de r�glement + "date_livraison" date default NULL, + "fk_adresse_livraison" integer, -- adresse de livraison + UNIQUE(ref) +); + +CREATE INDEX idx_llx_commande_ref ON llx_commande (ref); diff --git a/pgsql/tables/llx_commande_fournisseur.key.sql b/pgsql/tables/llx_commande_fournisseur.key.sql index 6065e0e134fc797eddd5f23d5d8dec02a6dbf995..70b39addd1269f612087f53e0caefc3677bb1380 100644 --- a/pgsql/tables/llx_commande_fournisseur.key.sql +++ b/pgsql/tables/llx_commande_fournisseur.key.sql @@ -1,32 +1,32 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - - --- Supprimme orphelins pour permettre mont�e de la cl� --- V4 DELETE llx_commande_fournisseur FROM llx_commande_fournisseur LEFT JOIN llx_societe ON llx_commande_fournisseur.fk_soc = llx_societe.idp WHERE llx_societe.idp IS NULL; - -ALTER TABLE llx_commande_fournisseur ADD INDEX idx_commande_fournisseur_fk_soc (fk_soc); -ALTER TABLE llx_commande_fournisseur ADD CONSTRAINT fk_commande_fournisseur_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + + +-- Supprimme orphelins pour permettre mont�e de la cl� +-- V4 DELETE llx_commande_fournisseur FROM llx_commande_fournisseur LEFT JOIN llx_societe ON llx_commande_fournisseur.fk_soc = llx_societe.idp WHERE llx_societe.idp IS NULL; + +ALTER TABLE llx_commande_fournisseur ADD INDEX idx_commande_fournisseur_fk_soc (fk_soc); +ALTER TABLE llx_commande_fournisseur ADD CONSTRAINT fk_commande_fournisseur_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); diff --git a/pgsql/tables/llx_commande_fournisseur.sql b/pgsql/tables/llx_commande_fournisseur.sql index c60e7567aa99d95063d59992c149c7f4ff9bfa15..f645669dd5df207ebe74b5b202531918dd035cd5 100644 --- a/pgsql/tables/llx_commande_fournisseur.sql +++ b/pgsql/tables/llx_commande_fournisseur.sql @@ -1,59 +1,59 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - - - - -create table llx_commande_fournisseur -( - rowid SERIAL PRIMARY KEY, - "tms" timestamp, - "fk_soc" integer NOT NULL, - "fk_projet" integer DEFAULT 0, -- projet auquel est rattache la commande - "ref" varchar(30) NOT NULL, -- order number - "date_creation" timestamp, -- date de creation - "date_valid" timestamp, -- date de validation - "date_cloture" timestamp, -- date de cloture - "date_commande" date, -- date de la commande - "fk_user_author" integer, -- createur de la commande - "fk_user_valid" integer, -- valideur de la commande - "fk_user_cloture" integer, -- auteur cloture - "source" smallint NOT NULL, - "fk_statut" smallint default 0, - "amount_ht" real default 0, - "remise_percent" real default 0, - "remise" real default 0, - "tva" real default 0, - "total_ht" real default 0, - "total_ttc" real default 0, - "note" text, - "note_public" text, - "model_pdf" varchar(50), - "fk_methode_commande" integer default 0, - UNIQUE(ref) -); - -CREATE INDEX idx_llx_commande_fournisseur_ref ON llx_commande_fournisseur (ref); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + + + + +create table llx_commande_fournisseur +( + rowid SERIAL PRIMARY KEY, + "tms" timestamp, + "fk_soc" integer NOT NULL, + "fk_projet" integer DEFAULT 0, -- projet auquel est rattache la commande + "ref" varchar(30) NOT NULL, -- order number + "date_creation" timestamp, -- date de creation + "date_valid" timestamp, -- date de validation + "date_cloture" timestamp, -- date de cloture + "date_commande" date, -- date de la commande + "fk_user_author" integer, -- createur de la commande + "fk_user_valid" integer, -- valideur de la commande + "fk_user_cloture" integer, -- auteur cloture + "source" smallint NOT NULL, + "fk_statut" smallint default 0, + "amount_ht" real default 0, + "remise_percent" real default 0, + "remise" real default 0, + "tva" real default 0, + "total_ht" real default 0, + "total_ttc" real default 0, + "note" text, + "note_public" text, + "model_pdf" varchar(50), + "fk_methode_commande" integer default 0, + UNIQUE(ref) +); + +CREATE INDEX idx_llx_commande_fournisseur_ref ON llx_commande_fournisseur (ref); diff --git a/pgsql/tables/llx_commande_fournisseur_log.sql b/pgsql/tables/llx_commande_fournisseur_log.sql index 3dc1d06a5ab68e1cb0a506ba58eb23ede77fb253..122fdfcd8de5934ee6f2565f0e2aaeab11c2eef8 100644 --- a/pgsql/tables/llx_commande_fournisseur_log.sql +++ b/pgsql/tables/llx_commande_fournisseur_log.sql @@ -1,35 +1,35 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - -create table llx_commande_fournisseur_log -( - rowid SERIAL PRIMARY KEY, - "tms" timestamp, - "datelog" timestamp, - "fk_commande" integer NOT NULL, - "fk_statut" smallint NOT NULL, - "fk_user" integer NOT NULL -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + +create table llx_commande_fournisseur_log +( + rowid SERIAL PRIMARY KEY, + "tms" timestamp, + "datelog" timestamp, + "fk_commande" integer NOT NULL, + "fk_statut" smallint NOT NULL, + "fk_user" integer NOT NULL +); diff --git a/pgsql/tables/llx_commande_fournisseurdet.sql b/pgsql/tables/llx_commande_fournisseurdet.sql index 83e5ccae71a59bc6b23f580b3967f8310d248493..2c4d88d6915275d2f28415f52b828efdd2ed827b 100644 --- a/pgsql/tables/llx_commande_fournisseurdet.sql +++ b/pgsql/tables/llx_commande_fournisseurdet.sql @@ -1,40 +1,40 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- =================================================================== - -create table llx_commande_fournisseurdet -( - rowid SERIAL PRIMARY KEY, - "fk_commande" integer, - "fk_product" integer, - "ref" varchar(50), - "label" varchar(255), - "description" text, - "tva_tx" real DEFAULT 19.6, -- taux tva - "qty" real, -- quantit� - "remise_percent" real DEFAULT 0, -- pourcentage de remise - "remise" real DEFAULT 0, -- montant de la remise - "subprice" real, -- prix avant remise - "price" real -- prix final -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- =================================================================== + +create table llx_commande_fournisseurdet +( + rowid SERIAL PRIMARY KEY, + "fk_commande" integer, + "fk_product" integer, + "ref" varchar(50), + "label" varchar(255), + "description" text, + "tva_tx" real DEFAULT 19.6, -- taux tva + "qty" real, -- quantit� + "remise_percent" real DEFAULT 0, -- pourcentage de remise + "remise" real DEFAULT 0, -- montant de la remise + "subprice" real, -- prix avant remise + "price" real -- prix final +); diff --git a/pgsql/tables/llx_commandedet.sql b/pgsql/tables/llx_commandedet.sql index a28e23261468d834d5d2df32654507f29c1caca2..f9b69756dff0386978bd0d92c760e0ba2092c2e6 100644 --- a/pgsql/tables/llx_commandedet.sql +++ b/pgsql/tables/llx_commandedet.sql @@ -1,46 +1,46 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- =================================================================== - -create table llx_commandedet -( - rowid SERIAL PRIMARY KEY, - "fk_commande" integer, - "fk_product" integer, - "label" varchar(255), - "description" text, - "tva_tx" real, -- taux tva - "qty" real, -- quantit� - "remise_percent" real DEFAULT 0, -- pourcentage de remise - "remise" real DEFAULT 0, -- montant de la remise - "fk_remise_except" integer NULL, -- Lien vers table des remises fixes - "subprice" real, -- prix avant remise - "price" real, -- prix final - "total_ht" real, -- Total HT de la ligne toute quantit� et incluant remise ligne et globale - "total_tva" real, -- Total TVA de la ligne toute quantit� et incluant remise ligne et globale - "total_ttc" real, -- Total TTC de la ligne toute quantit� et incluant remise ligne et globale - "info_bits" integer DEFAULT 0, -- TVA NPR ou non - "coef" real, -- coefficient de marge - "rang" integer DEFAULT 0 -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- =================================================================== + +create table llx_commandedet +( + rowid SERIAL PRIMARY KEY, + "fk_commande" integer, + "fk_product" integer, + "label" varchar(255), + "description" text, + "tva_tx" real, -- taux tva + "qty" real, -- quantit� + "remise_percent" real DEFAULT 0, -- pourcentage de remise + "remise" real DEFAULT 0, -- montant de la remise + "fk_remise_except" integer NULL, -- Lien vers table des remises fixes + "subprice" real, -- prix avant remise + "price" real, -- prix final + "total_ht" real, -- Total HT de la ligne toute quantit� et incluant remise ligne et globale + "total_tva" real, -- Total TVA de la ligne toute quantit� et incluant remise ligne et globale + "total_ttc" real, -- Total TTC de la ligne toute quantit� et incluant remise ligne et globale + "info_bits" integer DEFAULT 0, -- TVA NPR ou non + "coef" real, -- coefficient de marge + "rang" integer DEFAULT 0 +); diff --git a/pgsql/tables/llx_compta.sql b/pgsql/tables/llx_compta.sql index 5e58525e06155ed2ac9ab9d1b3fae34634193542..b5de8b705280545c349af35d17b5dbe5f0c47e96 100644 --- a/pgsql/tables/llx_compta.sql +++ b/pgsql/tables/llx_compta.sql @@ -1,40 +1,40 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2000-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - - -create table llx_compta -( - rowid SERIAL PRIMARY KEY, - "datec" timestamp, - "datev" date, -- date de valeur - "amount" real DEFAULT 0 NOT NULL , - "label" varchar(255), - "fk_compta_account" integer, - "fk_user_author" integer, - "fk_user_valid" integer, - "valid" smallint DEFAULT 0, - "note" text -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2000-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + + +create table llx_compta +( + rowid SERIAL PRIMARY KEY, + "datec" timestamp, + "datev" date, -- date de valeur + "amount" real DEFAULT 0 NOT NULL , + "label" varchar(255), + "fk_compta_account" integer, + "fk_user_author" integer, + "fk_user_valid" integer, + "valid" smallint DEFAULT 0, + "note" text +); diff --git a/pgsql/tables/llx_compta_account.sql b/pgsql/tables/llx_compta_account.sql index 4338b9ce63035cefae1af02b96bd80878acf87a8..82403ed14a47df42fbe099bcf08d6ab01b599888 100644 --- a/pgsql/tables/llx_compta_account.sql +++ b/pgsql/tables/llx_compta_account.sql @@ -1,36 +1,36 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2000-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- $Id$ --- $Source$ --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- =================================================================== - - -create table llx_compta_account -( - rowid SERIAL PRIMARY KEY, - "datec" timestamp, - "number" varchar(12), - "label" varchar(255), - "fk_user_author" integer, - "note" text -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2000-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- $Id$ +-- $Source$ +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- =================================================================== + + +create table llx_compta_account +( + rowid SERIAL PRIMARY KEY, + "datec" timestamp, + "number" varchar(12), + "label" varchar(255), + "fk_user_author" integer, + "note" text +); diff --git a/pgsql/tables/llx_compta_compte_generaux.sql b/pgsql/tables/llx_compta_compte_generaux.sql index 7336b46c54060ac1f44efb6eb89bdd9b94030d7e..bfb6b718879dbdecc2c8a63fe8462f2242537ba2 100644 --- a/pgsql/tables/llx_compta_compte_generaux.sql +++ b/pgsql/tables/llx_compta_compte_generaux.sql @@ -1,39 +1,39 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- =================================================================== --- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =================================================================== - - -create table llx_compta_compte_generaux -( - rowid SERIAL PRIMARY KEY, - "date_creation" timestamp, - "numero" varchar(50), - "intitule" varchar(255), - "fk_user_author" integer, - "note" text, - UNIQUE(numero) -); - -CREATE INDEX idx_llx_compta_compte_generaux_numero ON llx_compta_compte_generaux (numero); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- =================================================================== +-- Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =================================================================== + + +create table llx_compta_compte_generaux +( + rowid SERIAL PRIMARY KEY, + "date_creation" timestamp, + "numero" varchar(50), + "intitule" varchar(255), + "fk_user_author" integer, + "note" text, + UNIQUE(numero) +); + +CREATE INDEX idx_llx_compta_compte_generaux_numero ON llx_compta_compte_generaux (numero); diff --git a/pgsql/tables/llx_cond_reglement.sql b/pgsql/tables/llx_cond_reglement.sql index 71469d4da38c53590381ee59ecab1b18113780fc..e8319caf8e174789a30debb5f93703b66208202f 100644 --- a/pgsql/tables/llx_cond_reglement.sql +++ b/pgsql/tables/llx_cond_reglement.sql @@ -1,38 +1,38 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - -create table llx_cond_reglement -( - rowid integer PRIMARY KEY, - "code" varchar(16), - "sortorder" smallint, - "active" smallint DEFAULT 1, - "libelle" varchar(255), - "libelle_facture" text, - "fdm" smallint, -- reglement fin de mois - "nbjour" smallint, - "decalage" smallint -); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + +create table llx_cond_reglement +( + rowid integer PRIMARY KEY, + "code" varchar(16), + "sortorder" smallint, + "active" smallint DEFAULT 1, + "libelle" varchar(255), + "libelle_facture" text, + "fdm" smallint, -- reglement fin de mois + "nbjour" smallint, + "decalage" smallint +); diff --git a/pgsql/tables/llx_const.sql b/pgsql/tables/llx_const.sql index 90adee93c61fcb3fbeb6593e5cae637fae7331cc..03fbd8ed91cf2a09594e747c761491ff6655bfeb 100644 --- a/pgsql/tables/llx_const.sql +++ b/pgsql/tables/llx_const.sql @@ -1,43 +1,43 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- =========================================================================== --- --- Definitions des constantes utilis�s comme parametres de configuration --- - - -create table llx_const -( - rowid SERIAL PRIMARY KEY, - "name" varchar(255), - "value" text, -- max 65535 caracteres - "type" varchar(6) CHECK (type IN ('yesno','texte','chaine')) , - "visible" smallint DEFAULT 1 NOT NULL, - "note" text, - UNIQUE(name) -); - -CREATE INDEX idx_llx_const_name ON llx_const (name); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- =========================================================================== +-- +-- Definitions des constantes utilis�s comme parametres de configuration +-- + + +create table llx_const +( + rowid SERIAL PRIMARY KEY, + "name" varchar(255), + "value" text, -- max 65535 caracteres + "type" varchar(6) CHECK (type IN ('yesno','texte','chaine')) , + "visible" smallint DEFAULT 1 NOT NULL, + "note" text, + UNIQUE(name) +); + +CREATE INDEX idx_llx_const_name ON llx_const (name); diff --git a/pgsql/tables/llx_contrat.key.sql b/pgsql/tables/llx_contrat.key.sql index 6be1985a301cdc965787757fe50f51ddf609bdbd..f680c5430ae685c3bf7a8ed1941ca10dd3ca37c8 100644 --- a/pgsql/tables/llx_contrat.key.sql +++ b/pgsql/tables/llx_contrat.key.sql @@ -1,38 +1,38 @@ --- Generated from dolibarr_mysql2pgsql --- (c) 2004, PostgreSQL Inc. --- (c) 2005, Laurent Destailleur. - --- ============================================================================ --- Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> --- Copyright (C) 2004-2005 Laurent Destailleur <eldy@users.sourceforge.net> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- --- $Id$ --- $Source$ --- --- ============================================================================ - - --- Supprimme orhpelins pour permettre mont�e de la cl� --- V4 DELETE llx_contratdet FROM llx_contratdet, llx_contrat LEFT JOIN llx_societe ON llx_contrat.fk_soc = llx_societe.idp WHERE llx_contratdet.fk_contrat = llx_contrat.rowid AND llx_societe.idp IS NULL; --- V4 DELETE llx_contrat FROM llx_contrat LEFT JOIN llx_societe ON llx_contrat.fk_soc = llx_societe.idp WHERE llx_societe.idp IS NULL; --- V4 DELETE llx_contrat FROM llx_contrat LEFT JOIN llx_user ON llx_contrat.fk_user_author = llx_user.rowid WHERE llx_user.rowid IS NULL; - -ALTER TABLE llx_contrat ADD INDEX idx_contrat_fk_soc (fk_soc); -ALTER TABLE llx_contrat ADD INDEX idx_contrat_fk_user_author (fk_user_author); - -ALTER TABLE llx_contrat ADD CONSTRAINT fk_contrat_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); +-- Generated from dolibarr_mysql2pgsql +-- (c) 2004, PostgreSQL Inc. +-- (c) 2005, Laurent Destailleur. + +-- ============================================================================ +-- Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> +-- Copyright (C) 2004-2005 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-- +-- $Id$ +-- $Source$ +-- +-- ============================================================================ + + +-- Supprimme orhpelins pour permettre mont�e de la cl� +-- V4 DELETE llx_contratdet FROM llx_contratdet, llx_contrat LEFT JOIN llx_societe ON llx_contrat.fk_soc = llx_societe.idp WHERE llx_contratdet.fk_contrat = llx_contrat.rowid AND llx_societe.idp IS NULL; +-- V4 DELETE llx_contrat FROM llx_contrat LEFT JOIN llx_societe ON llx_contrat.fk_soc = llx_societe.idp WHERE llx_societe.idp IS NULL; +-- V4 DELETE llx_contrat FROM llx_contrat LEFT JOIN llx_user ON llx_contrat.fk_user_author = llx_user.rowid WHERE llx_user.rowid IS NULL; + +ALTER TABLE llx_contrat ADD INDEX idx_contrat_fk_soc (fk_soc); +ALTER TABLE llx_contrat ADD INDEX idx_contrat_fk_user_author (fk_user_author); + +ALTER TABLE llx_contrat ADD CONSTRAINT fk_contrat_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe (idp); ALTER TABLE llx_contrat ADD CONSTRAINT fk_contrat_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); \ No newline at end of file