From ff1e10683bf21345ef4a3ce14667e5879216abfa Mon Sep 17 00:00:00 2001 From: YuCheng Hu Date: Sat, 12 Jun 2010 07:24:12 +0000 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=B0=20trunk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +YUCHENG HU+ git-svn-id: https://svn.code.sf.net/p/hawebs/svn@141 a2543c7e-f6e9-4f8a-8bff-1ffc34733512 --- .../customerportal/Accounts/AccountDetail.php | 38 + .../trunk/customerportal/Accounts/index.html | 28 + .../trunk/customerportal/Accounts/index.php | 27 + .../trunk/customerportal/Acknowledgment.txt | 11 + .../Contacts/ContactsDetail.php | 39 + .../customerportal/Contacts/ContactsList.php | 58 + .../trunk/customerportal/Contacts/index.html | 23 + .../trunk/customerportal/Contacts/index.php | 37 + .../customerportal/CustomerAuthenticate.php | 96 + .../Documents/DocumentDetail.php | 40 + .../Documents/DocumentsList.php | 45 + .../trunk/customerportal/Documents/index.html | 28 + .../trunk/customerportal/Documents/index.php | 37 + .../customerportal/Documents/updateCount.php | 12 + .../trunk/customerportal/Faq/FaqDetail.php | 125 + .../customerportal/Faq/SaveFaqComment.php | 25 + oss/vtiger/trunk/customerportal/Faq/Utils.php | 328 + .../trunk/customerportal/Faq/index.html | 159 + oss/vtiger/trunk/customerportal/Faq/index.php | 104 + .../customerportal/HelpDesk/NewTicket.php | 196 + .../customerportal/HelpDesk/SaveTicket.php | 88 + .../customerportal/HelpDesk/SearchForm.php | 60 + .../customerportal/HelpDesk/TicketDetail.php | 247 + .../customerportal/HelpDesk/TicketSearch.php | 40 + .../customerportal/HelpDesk/TicketsList.php | 167 + .../trunk/customerportal/HelpDesk/Utils.php | 227 + .../trunk/customerportal/HelpDesk/index.html | 64 + .../trunk/customerportal/HelpDesk/index.php | 89 + .../trunk/customerportal/INSTALLATION.txt | 1 + .../customerportal/Invoice/InvoiceDetail.php | 41 + .../customerportal/Invoice/InvoiceList.php | 46 + .../trunk/customerportal/Invoice/index.html | 28 + .../trunk/customerportal/Invoice/index.php | 66 + .../customerportal/LICENSE_AGREEMENT.txt | 173 + .../trunk/customerportal/MySettings.php | 165 + .../trunk/customerportal/PortalConfig.php | 40 + .../customerportal/Products/ProductDetail.php | 38 + .../customerportal/Products/ProductList.php | 54 + .../trunk/customerportal/Products/index.html | 23 + .../trunk/customerportal/Products/index.php | 32 + .../customerportal/Quotes/QuoteDetail.php | 39 + .../customerportal/Quotes/QuotesList.php | 58 + .../trunk/customerportal/Quotes/index.html | 28 + .../trunk/customerportal/Quotes/index.php | 40 + .../customerportal/Services/ServiceDetail.php | 39 + .../customerportal/Services/ServiceList.php | 51 + .../trunk/customerportal/Services/index.html | 28 + .../trunk/customerportal/Services/index.php | 40 + .../trunk/customerportal/css/dropdown.css | 176 + oss/vtiger/trunk/customerportal/css/style.css | 904 +++ oss/vtiger/trunk/customerportal/footer.html | 88 + oss/vtiger/trunk/customerportal/header.html | 97 + .../trunk/customerportal/images/category.gif | Bin 0 -> 627 bytes .../trunk/customerportal/images/email.gif | Bin 0 -> 211 bytes .../trunk/customerportal/images/faq.gif | Bin 0 -> 99 bytes .../trunk/customerportal/images/favorite.gif | Bin 0 -> 233 bytes .../trunk/customerportal/images/loginBg.gif | Bin 0 -> 1072 bytes .../customerportal/images/loginBgbig.gif | Bin 0 -> 1345 bytes .../customerportal/images/loginBgbig.jpg | Bin 0 -> 481 bytes .../customerportal/images/loginBottomBg.gif | Bin 0 -> 108 bytes .../customerportal/images/loginBottomURL.gif | Bin 0 -> 444 bytes .../customerportal/images/loginBtnSignin.gif | Bin 0 -> 1778 bytes .../images/loginSIBottomLeft.gif | Bin 0 -> 99 bytes .../images/loginSIBottomRight.gif | Bin 0 -> 98 bytes .../customerportal/images/loginSITopLeft.gif | Bin 0 -> 99 bytes .../customerportal/images/loginSITopRight.gif | Bin 0 -> 98 bytes .../customerportal/images/loginTopBg.gif | Bin 0 -> 1068 bytes .../customerportal/images/loginTopShade.gif | Bin 0 -> 121 bytes .../customerportal/images/loginVtigerCRM.gif | Bin 0 -> 2549 bytes .../trunk/customerportal/images/minus.gif | Bin 0 -> 64 bytes .../trunk/customerportal/images/plus.gif | Bin 0 -> 67 bytes .../trunk/customerportal/images/print.gif | Bin 0 -> 230 bytes .../trunk/customerportal/images/products.gif | Bin 0 -> 372 bytes .../trunk/customerportal/images/status.gif | Bin 0 -> 3870 bytes .../customerportal/images/tabSeperatorBg.gif | Bin 0 -> 862 bytes .../customerportal/images/vtiger-crm.gif | Bin 0 -> 497 bytes oss/vtiger/trunk/customerportal/include.php | 23 + .../customerportal/include/utils/utils.php | 294 + oss/vtiger/trunk/customerportal/index.php | 280 + .../trunk/customerportal/js/acdropdown.js | 1546 +++++ oss/vtiger/trunk/customerportal/js/cookies.js | 33 + oss/vtiger/trunk/customerportal/js/general.js | 115 + .../trunk/customerportal/js/getobject2.js | 126 + oss/vtiger/trunk/customerportal/js/modomt.js | 259 + .../trunk/customerportal/js/prototype.js | 2011 ++++++ .../customerportal/language/en_us.lang.php | 411 ++ oss/vtiger/trunk/customerportal/login.php | 179 + .../customerportal/nusoap/lib/nusoap.php | 5586 +++++++++++++++++ .../trunk/customerportal/supportpage.php | 74 + oss/vtiger/trunk/customerportal/version.php | 16 + 90 files changed, 15686 insertions(+) create mode 100644 oss/vtiger/trunk/customerportal/Accounts/AccountDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Accounts/index.html create mode 100644 oss/vtiger/trunk/customerportal/Accounts/index.php create mode 100644 oss/vtiger/trunk/customerportal/Acknowledgment.txt create mode 100644 oss/vtiger/trunk/customerportal/Contacts/ContactsDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Contacts/ContactsList.php create mode 100644 oss/vtiger/trunk/customerportal/Contacts/index.html create mode 100644 oss/vtiger/trunk/customerportal/Contacts/index.php create mode 100644 oss/vtiger/trunk/customerportal/CustomerAuthenticate.php create mode 100644 oss/vtiger/trunk/customerportal/Documents/DocumentDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Documents/DocumentsList.php create mode 100644 oss/vtiger/trunk/customerportal/Documents/index.html create mode 100644 oss/vtiger/trunk/customerportal/Documents/index.php create mode 100644 oss/vtiger/trunk/customerportal/Documents/updateCount.php create mode 100644 oss/vtiger/trunk/customerportal/Faq/FaqDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Faq/SaveFaqComment.php create mode 100644 oss/vtiger/trunk/customerportal/Faq/Utils.php create mode 100644 oss/vtiger/trunk/customerportal/Faq/index.html create mode 100644 oss/vtiger/trunk/customerportal/Faq/index.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/NewTicket.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/SaveTicket.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/SearchForm.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/TicketDetail.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/TicketSearch.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/TicketsList.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/Utils.php create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/index.html create mode 100644 oss/vtiger/trunk/customerportal/HelpDesk/index.php create mode 100644 oss/vtiger/trunk/customerportal/INSTALLATION.txt create mode 100644 oss/vtiger/trunk/customerportal/Invoice/InvoiceDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Invoice/InvoiceList.php create mode 100644 oss/vtiger/trunk/customerportal/Invoice/index.html create mode 100644 oss/vtiger/trunk/customerportal/Invoice/index.php create mode 100644 oss/vtiger/trunk/customerportal/LICENSE_AGREEMENT.txt create mode 100644 oss/vtiger/trunk/customerportal/MySettings.php create mode 100644 oss/vtiger/trunk/customerportal/PortalConfig.php create mode 100644 oss/vtiger/trunk/customerportal/Products/ProductDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Products/ProductList.php create mode 100644 oss/vtiger/trunk/customerportal/Products/index.html create mode 100644 oss/vtiger/trunk/customerportal/Products/index.php create mode 100644 oss/vtiger/trunk/customerportal/Quotes/QuoteDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Quotes/QuotesList.php create mode 100644 oss/vtiger/trunk/customerportal/Quotes/index.html create mode 100644 oss/vtiger/trunk/customerportal/Quotes/index.php create mode 100644 oss/vtiger/trunk/customerportal/Services/ServiceDetail.php create mode 100644 oss/vtiger/trunk/customerportal/Services/ServiceList.php create mode 100644 oss/vtiger/trunk/customerportal/Services/index.html create mode 100644 oss/vtiger/trunk/customerportal/Services/index.php create mode 100644 oss/vtiger/trunk/customerportal/css/dropdown.css create mode 100644 oss/vtiger/trunk/customerportal/css/style.css create mode 100644 oss/vtiger/trunk/customerportal/footer.html create mode 100644 oss/vtiger/trunk/customerportal/header.html create mode 100644 oss/vtiger/trunk/customerportal/images/category.gif create mode 100644 oss/vtiger/trunk/customerportal/images/email.gif create mode 100644 oss/vtiger/trunk/customerportal/images/faq.gif create mode 100644 oss/vtiger/trunk/customerportal/images/favorite.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginBg.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginBgbig.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginBgbig.jpg create mode 100644 oss/vtiger/trunk/customerportal/images/loginBottomBg.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginBottomURL.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginBtnSignin.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginSIBottomLeft.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginSIBottomRight.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginSITopLeft.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginSITopRight.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginTopBg.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginTopShade.gif create mode 100644 oss/vtiger/trunk/customerportal/images/loginVtigerCRM.gif create mode 100644 oss/vtiger/trunk/customerportal/images/minus.gif create mode 100644 oss/vtiger/trunk/customerportal/images/plus.gif create mode 100644 oss/vtiger/trunk/customerportal/images/print.gif create mode 100644 oss/vtiger/trunk/customerportal/images/products.gif create mode 100644 oss/vtiger/trunk/customerportal/images/status.gif create mode 100644 oss/vtiger/trunk/customerportal/images/tabSeperatorBg.gif create mode 100644 oss/vtiger/trunk/customerportal/images/vtiger-crm.gif create mode 100644 oss/vtiger/trunk/customerportal/include.php create mode 100644 oss/vtiger/trunk/customerportal/include/utils/utils.php create mode 100644 oss/vtiger/trunk/customerportal/index.php create mode 100644 oss/vtiger/trunk/customerportal/js/acdropdown.js create mode 100644 oss/vtiger/trunk/customerportal/js/cookies.js create mode 100644 oss/vtiger/trunk/customerportal/js/general.js create mode 100644 oss/vtiger/trunk/customerportal/js/getobject2.js create mode 100644 oss/vtiger/trunk/customerportal/js/modomt.js create mode 100644 oss/vtiger/trunk/customerportal/js/prototype.js create mode 100644 oss/vtiger/trunk/customerportal/language/en_us.lang.php create mode 100644 oss/vtiger/trunk/customerportal/login.php create mode 100644 oss/vtiger/trunk/customerportal/nusoap/lib/nusoap.php create mode 100644 oss/vtiger/trunk/customerportal/supportpage.php create mode 100644 oss/vtiger/trunk/customerportal/version.php diff --git a/oss/vtiger/trunk/customerportal/Accounts/AccountDetail.php b/oss/vtiger/trunk/customerportal/Accounts/AccountDetail.php new file mode 100644 index 00000000..e2e51638 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Accounts/AccountDetail.php @@ -0,0 +1,38 @@ + "$accountid", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + '.getTranslatedString('LBL_NOT_AUTHORISED').' + '; + die(); + } + $noteinfo = $result[0][$block]; + echo '
'; + echo getblock_fieldlist($noteinfo); + + echo ''; + echo ''; + echo ''; +} + +?> diff --git a/oss/vtiger/trunk/customerportal/Accounts/index.html b/oss/vtiger/trunk/customerportal/Accounts/index.html new file mode 100644 index 00000000..c7f7620a --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Accounts/index.html @@ -0,0 +1,28 @@ + + + + +
+ + + + + + + + +
+ + + + + + diff --git a/oss/vtiger/trunk/customerportal/Accounts/index.php b/oss/vtiger/trunk/customerportal/Accounts/index.php new file mode 100644 index 00000000..2d91b513 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Accounts/index.php @@ -0,0 +1,27 @@ +$customerid); + $accountid = $client->call('get_check_account_id', $params, $Server_Path, $Server_Path); +} +else + $accountid = $_REQUEST['id']; + +if($accountid != '') + include("AccountDetail.php"); +?> diff --git a/oss/vtiger/trunk/customerportal/Acknowledgment.txt b/oss/vtiger/trunk/customerportal/Acknowledgment.txt new file mode 100644 index 00000000..c9231ea8 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Acknowledgment.txt @@ -0,0 +1,11 @@ +ACKNOWLEDGMENTS: + +The vtiger Customer Portal contains the software product of other developers. +We wish to acknowledge the following third party software that are used in vtiger Customer Portal: + +1. GNU LGPL License for usage of nusoap downloaded from http://sourceforge.net/projects/nusoap + + + +--------------------------------------------- +© 2005 www.vtiger.com. All Rights Reserved. diff --git a/oss/vtiger/trunk/customerportal/Contacts/ContactsDetail.php b/oss/vtiger/trunk/customerportal/Contacts/ContactsDetail.php new file mode 100644 index 00000000..1dff019b --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Contacts/ContactsDetail.php @@ -0,0 +1,39 @@ + "$id", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo '
'.getTranslatedString('LBL_NOT_AUTHORISED').'
'; + die(); + } + $noteinfo = $result[0][$block]; + echo '
'; + echo getblock_fieldlist($noteinfo); + + echo ''; + echo ''; + echo ''; +} + +?> diff --git a/oss/vtiger/trunk/customerportal/Contacts/ContactsList.php b/oss/vtiger/trunk/customerportal/Contacts/ContactsList.php new file mode 100644 index 00000000..95bdebce --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Contacts/ContactsList.php @@ -0,0 +1,58 @@ + + '.getTranslatedString("LBL_CONTACTS").''; + $allow_all = $client->call('show_all',array('module'=>'Contacts'),$Server_Path, $Server_Path); + + if($allow_all == 'true'){ + echo ' '.getTranslatedString('SHOW').'  '; + } + + echo '
+ '; + + + $block = "Contacts"; + $sessionid = $_SESSION['customer_sessionid']; + $params = array('id' => "$customerid", 'block'=>"$block",'sessionid'=>"$sessionid",'onlymine'=>$onlymine); + $result = $client->call('get_list_values', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + +
'.getTranslatedString("LBL_NOT_AUTHORISED").'
'; + die(); + } + + echo getblock_fieldlistview($result,$block); +} + + +?> diff --git a/oss/vtiger/trunk/customerportal/Contacts/index.html b/oss/vtiger/trunk/customerportal/Contacts/index.html new file mode 100644 index 00000000..34a645c9 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Contacts/index.html @@ -0,0 +1,23 @@ + + + + +
+ + + + + + +
+ diff --git a/oss/vtiger/trunk/customerportal/Contacts/index.php b/oss/vtiger/trunk/customerportal/Contacts/index.php new file mode 100644 index 00000000..ecfaaa1d --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Contacts/index.php @@ -0,0 +1,37 @@ +
'; + +?> diff --git a/oss/vtiger/trunk/customerportal/CustomerAuthenticate.php b/oss/vtiger/trunk/customerportal/CustomerAuthenticate.php new file mode 100644 index 00000000..1c14971c --- /dev/null +++ b/oss/vtiger/trunk/customerportal/CustomerAuthenticate.php @@ -0,0 +1,96 @@ + "$username", + 'user_password'=>"$password", + 'version' => "$version"); + + +$result = $client->call('authenticate_user', $params, $Server_Path, $Server_Path); +//The following are the debug informations +$err = $client->getError(); +if ($err) +{ + //Uncomment the following lines to get the error message in login screen itself. + /* + echo '

Error Message

' . $err . '
'; + echo '

request

' . htmlspecialchars($client->request, ENT_QUOTES) . '
'; + echo '

response

' . htmlspecialchars($client->response, ENT_QUOTES) . '
'; + echo '

debug

' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '
'; + exit; + */ + $login_error_msg = getTranslatedString("LBL_CANNOT_CONNECT_SERVER"); + $login_error_msg = base64_encode(' '.$login_error_msg.' '); + header("Location: login.php?login_error=$login_error_msg"); + exit; +} + +if(strtolower($result[0]['user_name']) == strtolower($username) && strtolower($result[0]['user_password']) == strtolower($password)) +{ + session_start(); + $_SESSION['customer_id'] = $result[0]['id']; + $_SESSION['customer_sessionid'] = $result[0]['sessionid']; + $_SESSION['customer_name'] = $result[0]['user_name']; + $_SESSION['last_login'] = $result[0]['last_login_time']; + $_SESSION['support_start_date'] = $result[0]['support_start_date']; + $_SESSION['support_end_date'] = $result[0]['support_end_date']; + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + $params1 = Array(Array('id' => "$customerid", 'sessionid'=>"$sessionid", 'flag'=>"login")); + + $result2 = $client->call('update_login_details', $params1, $Server_Path, $Server_Path); + + $params = array('customerid'=>$customerid); + $permission = $client->call('get_modules',$params,$Server_path,$Server_path); + $module = $permission[0]; + + if($permission == '') + { + echo getTranslatedString('LBL_NO_PERMISSION_FOR_ANY_MODULE'); + exit; + } + + // Store the permitted modules in session for re-use + $_SESSION['__permitted_modules'] = $permission; + + header("Location: index.php?action=index&module=$module"); +} +else +{ + if($result[0] == 'NOT COMPATIBLE'){ + $error_msg = getTranslatedString("LBL_VERSION_INCOMPATIBLE"); + }elseif($result[0] == 'INVALID_USERNAME_OR_PASSWORD') { + $error_msg = getTranslatedString("LBL_ENTER_VALID_USER"); + }elseif($result[0] == 'MORE_THAN_ONE_USER'){ + $error_msg = getTranslatedString("MORE_THAN_ONE_USER"); + } + else + $error_msg = getTranslatedString("LBL_CANNOT_CONNECT_SERVER"); + + $login_error_msg = base64_encode(' '.$error_msg.' '); + header("Location: login.php?login_error=$login_error_msg"); +} + +?> diff --git a/oss/vtiger/trunk/customerportal/Documents/DocumentDetail.php b/oss/vtiger/trunk/customerportal/Documents/DocumentDetail.php new file mode 100644 index 00000000..c386b4e5 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Documents/DocumentDetail.php @@ -0,0 +1,40 @@ +'; +if($note_id != '') +{ + + $params = array('id' => "$note_id", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + '.getTranslatedString('LBL_NOT_AUTHORISED').' + '; + die(); + } + $noteinfo = $result[0][$block]; + + echo '
'; + echo getblock_fieldlist($noteinfo); + + echo ''; + echo ''; + echo ''; +} +?> diff --git a/oss/vtiger/trunk/customerportal/Documents/DocumentsList.php b/oss/vtiger/trunk/customerportal/Documents/DocumentsList.php new file mode 100644 index 00000000..c9110aad --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Documents/DocumentsList.php @@ -0,0 +1,45 @@ + + '.getTranslatedString("LBL_NOTES_INFORMATION").''; + $allow_all = $client->call('show_all',array('Documents'),$Server_Path, $Server_Path); + + if($allow_all == 'true'){ + echo ' '.getTranslatedString('SHOW').'  '; + } + + echo '
+ '; + +if ($customerid != '' ) +{ + $block = "Documents"; + $params = array('id' => "$customerid", 'block'=>"$block",'sessionid'=>$sessionid,'onlymine'=>$onlymine); + $result = $client->call('get_list_values', $params, $Server_Path, $Server_Path); + echo getblock_fieldlistview($result,$block); +} +?> diff --git a/oss/vtiger/trunk/customerportal/Documents/index.html b/oss/vtiger/trunk/customerportal/Documents/index.html new file mode 100644 index 00000000..c7f7620a --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Documents/index.html @@ -0,0 +1,28 @@ + + +
+ +
+ + + + + + +
+ + + + + + diff --git a/oss/vtiger/trunk/customerportal/Documents/index.php b/oss/vtiger/trunk/customerportal/Documents/index.php new file mode 100644 index 00000000..74be11b0 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Documents/index.php @@ -0,0 +1,37 @@ +
'; + +?> diff --git a/oss/vtiger/trunk/customerportal/Documents/updateCount.php b/oss/vtiger/trunk/customerportal/Documents/updateCount.php new file mode 100644 index 00000000..7629dce6 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Documents/updateCount.php @@ -0,0 +1,12 @@ +call('updateCount',array($id),$Server_Path,$Server_Path); + +?> diff --git a/oss/vtiger/trunk/customerportal/Faq/FaqDetail.php b/oss/vtiger/trunk/customerportal/Faq/FaqDetail.php new file mode 100644 index 00000000..d3a0503d --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Faq/FaqDetail.php @@ -0,0 +1,125 @@ +'; +for($i=0;$i + '.getTranslatedString('LBL_FAQ_DETAIL').''; + $list .= ''.$faq_array[$i]['question']; + $list .= '

'.getTranslatedString('LBL_ANSWER').'
'.$faq_array[$i]['answer'].' + '; + + $list .= ''.getTranslatedString('LBL_COMMENTS').''; + + $list .= ' + + +
+ '; + + for($j=0;$j<$comments_count;$j++) + { + $list .= ' + + + + '; + } + $list .= ' +
'.($comments_count-$j).' + '.$comments_array[$j]; + + if ($createdtime_array[$j]!="0000-00-00 00:00:00") + $list .= '
'.getTranslatedString('LBL_ADDED_ON').$createdtime_array[$j].''; + + $list .= ' +
+
+ + + +   +   + + '.getTranslatedString('LBL_DOCUMENTS').''; + $module = 'Documents'; + $params = array('id' => "$faqid",'module'=>"$module", 'contactid'=>"$customerid",'sessionid'=>"$sessionid"); + $result = $client->call('get_documents', $params, $Server_Path, $Server_Path); + $list .= getblock_fieldlistview($result,$module); + $list .=' +   +   + + ' . + ' + + + + + + '.getTranslatedString('LBL_ADD_COMMENT').' + + + + + + + + + + + + +   + + + + + '.getPageOption().' + '; + } +} + +$list .= ' '; + +//This is added to get the FAQ details as a Popup on Mouse over +$list .= getArticleIdTime($faq_module_no,$faq_productid,$faq_category,$faq_createdtime,$faq_modifiedtime); + +echo $list; + + + + + +?> diff --git a/oss/vtiger/trunk/customerportal/Faq/SaveFaqComment.php b/oss/vtiger/trunk/customerportal/Faq/SaveFaqComment.php new file mode 100644 index 00000000..d6cab2f9 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Faq/SaveFaqComment.php @@ -0,0 +1,25 @@ + "$customerid", 'sessionid'=>"$sessionid", 'faqid'=>"$faqid", 'comment'=>"$comment")); +$result = $client->call('save_faq_comment', $params, $Server_Path, $Server_Path); + + +?> diff --git a/oss/vtiger/trunk/customerportal/Faq/Utils.php b/oss/vtiger/trunk/customerportal/Faq/Utils.php new file mode 100644 index 00000000..eccb55bb --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Faq/Utils.php @@ -0,0 +1,328 @@ +'.getTranslatedString('LBL_RECENTLY_CREATED').''; + $list .= '
'; + + for($i=0;$i'.$faq_array[$i]['question'].' + + + + + + + '; + } + if(!$record_exist) + $list .= getTranslatedString('LBL_NO_FAQ'); + + $list .= '
'.$faq_array[$i]['answer'].'
'; + return $list; +} +function ListFaqsPerCategory($category_index) +{ + $list = ''; + $category_array = $_SESSION['category_array']; + $faq_array = $_SESSION['faq_array']; + $category = $category_array[$category_index]; + $list = '
'.getTranslatedString('LNK_CATEGORY').': '.$category.'
'; + $list .= '
'; + + for($i=0;$i'.$faq_array[$i]['question'].' + + + + '; + } + } + if(!$flag) + $list .= getTranslatedString('LBL_NO_FAQ_IN_THIS_CATEGORY'); + $list .= '
'.$faq_array[$i]['answer'].'
'; + return $list; +} +function ListFaqsPerProduct($productid) +{ + $list = ''; + $product_array = $_SESSION['product_array']; + $faq_array = $_SESSION['faq_array']; + $list = '
'.getTranslatedString('LBL_PRODUCT').': '.getProductname($productid).'
'; + $list .= '
'; + + for($i=0;$i'.$faq_array[$i]['question'].' + + + + + + + '; + } + } + if(!$flag) + $list .= getTranslatedString('LBL_NO_FAQ_IN_THIS_PRODUCT'); + $list .= '
'.$faq_array[$i]['answer'].'
'; + return $list; +} + +function getArticleIdTime($faqid,$product_id,$faqcategory,$faqcreatedtime,$faqmodifiedtime) +{ + $list .='
+ + + + + + + + + + + + + + + + +
'.getTranslatedString('LBL_FAQ_ID').': '.$faqid.'
'.getTranslatedString('LBL_PRODUCT').': '.getProductName($product_id).'
'.getTranslatedString('LBL_CATEGORY').': '.$faqcategory.'
'.getTranslatedString('LBL_CREATED_DATE').': '.substr($faqcreatedtime,0,10).'
'.getTranslatedString('LBL_MODIFIED_DATE').': '.substr($faqmodifiedtime,0,10).'
+
'; + + return $list; +} +function getPageOption() +{ + $list .= ' + + + + + + +
'.getTranslatedString('LBL_PRINT_THIS_PAGE').''.getTranslatedString('LBL_EMAIL_THIS_PAGE').''.getTranslatedString('LBL_ADD_TO_FAVORITES').'
+ '; + $list .= ''; + + return $list; +} +function getProductName($productid) +{ + $product_array = $_SESSION['product_array']; + $productname = ''; + for($i=0;$i'.$category_array[$i].''; + } + $comboarray .= ''; + $comboarray .= ''; + for($i=0;$i'.$product_array[$i]['productname'].''; + } + $comboarray .= ''; + $comboarray .= ''; + return $comboarray; +} +function getSearchResult($search_text,$search_value,$search_by) +{ + $faq_array = $_SESSION['faq_array']; + + $list = '
'.getTranslatedString('LBL_SEARCH_RESULT').'
'; + $list .= '
'; + + if($search_value == 'All') + { + for($i=0;$i'.$faq_array[$i]['question'].' + + + + + + + + + + '; + } + } + if(!$record_exist) + $list .= getTranslatedString('LBL_NO_FAQ_IN_THIS_SEARCH_CRITERIA'); + } + elseif($search_by == 'category') + { + for($i=0;$i'.$faq_array[$i]['question'].' + + + + '; + } + } + if(!$record_exist) + $list .= getTranslatedString('LBL_NO_FAQ_IN_THIS_SEARCH_CRITERIA'); + } + elseif($search_by == 'products') + { + $product_array = $_SESSION['product_array']; + $faq_array = $_SESSION['faq_array']; + for($i=0;$i'.$faq_array[$j]['question'].' + + + + + + + '; + } + } + } + } + if(!$record_exist) + $list .= getTranslatedString('LBL_NO_FAQ_IN_THIS_SEARCH_CRITERIA'); + } + + $list .= '
'.$faq_array[$i]['answer'].'
'.getTranslatedString('LBL_CATEGORY').': '.$faq_array[$i]['category'].'
'.$faq_array[$i]['answer'].'
'.$faq_array[$j]['answer'].'
'; + return $list; +} + +function text_length($str){ + $length = strlen($str); + if($length > 25){ + $str = substr($str,0,25).".."; + return $str; + } + return $str; +} +?> diff --git a/oss/vtiger/trunk/customerportal/Faq/index.html b/oss/vtiger/trunk/customerportal/Faq/index.html new file mode 100644 index 00000000..a2596bdf --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Faq/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + + + +
 
+
+ + + +  in  + + +
+
+ + + + + + + +
+ 0 && $category_array !=null){ ?> + + + + + + + + + + + +
+
+ + + + + + +
+ '.text_length($category_array[$i]).''; + else + echo text_length($category_array[$i]); + ?> + + '.'('.$noof_faqs.')'.''; + else + echo '('.$noof_faqs.')'; + ?>
+
+
+ + + + + + + + + + + + + +
+
+ + + + + + +
+ + '.$product_array[$i]['productname'].''; + else + echo $product_array[$i]['productname']; + ?> + + '.'('.$noof_faqs.')'.''; + else + echo '('.$noof_faqs.')'; + ?> +
+
+
+ +
+ +
+ +
+ + + + + + + diff --git a/oss/vtiger/trunk/customerportal/Faq/index.php b/oss/vtiger/trunk/customerportal/Faq/index.php new file mode 100644 index 00000000..b8c97ffd --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Faq/index.php @@ -0,0 +1,104 @@ + "$customerid", 'sessionid'=>"$sessionid")); +$result = $client->call('get_KBase_details', $params, $Server_Path, $Server_Path); + +$category_array = $result[0]; +$faq_array = $result[2]; + +if(@array_key_exists('productid',$result[1][0]) && @array_key_exists('productname',$result[1][0])) + $product_array = $result[1]; +elseif(@array_key_exists('id',$result[1][0]) && @array_key_exists('question',$result[1][0]) && @array_key_exists('answer',$result[1][0])) + $faq_array = $result[1]; + +$_SESSION['product_array'] = $product_array; +$_SESSION['category_array'] = $category_array; +$_SESSION['faq_array'] = $faq_array; + +$search_text = $_REQUEST['search_text']; + + +include("Faq/Utils.php"); +include("Faq/index.html"); + +if($_REQUEST['fun'] == '') +{ + if(!empty($faq_array)) + echo getLatestlyCreatedFaqList(); +} +elseif($_REQUEST['fun'] == 'faqs') +{ + if($_REQUEST['category_index'] != '') + { + echo ListFaqsPerCategory($_REQUEST['category_index']); + } + elseif($_REQUEST['productid'] != '') + { + echo ListFaqsPerProduct($_REQUEST['productid']); + } + else + { + echo 'Wrong parameters'; + } +} +elseif($_REQUEST['fun'] == 'search') +{ + $search_text = $_REQUEST['search_text']; + $search_category = explode(":",$_REQUEST['search_category']); + $searchlist .= getSearchResult($search_text,$search_category[1],$search_category[0]); + echo $searchlist; +} +elseif($_REQUEST['fun'] == 'faq_detail') +{ + include("Faq/FaqDetail.php"); +} +elseif($_REQUEST['fun'] == 'faq_updatecomment') +{ + ?> + + +
+ + + + + '; + +?> diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/NewTicket.php b/oss/vtiger/trunk/customerportal/HelpDesk/NewTicket.php new file mode 100644 index 00000000..c979f0f2 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/NewTicket.php @@ -0,0 +1,196 @@ +"$customerid", 'sessionid'=>"$sessionid")); +$result = $client->call('get_combo_values', $params, $Server_Path, $Server_Path); + +$_SESSION['combolist'] = $result; +$combolist = $_SESSION['combolist']; +for($i=0;$i 0) + $productarray .= ','; + $productarray .= "'".$productslist[1][$i]."'"; + } +} +if($servicename == '#MODULE INACTIVE#' || $serviceid == '#MODULE INACTIVE#'){ + unset($servicename); + unset($serviceid); +} + +?> + + + + + + + + +
 
+    +


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
* + +
+ + + +   + '; + $list .= ''; + for($i=0;$i'.$servicename[$i].''; + } + $list .= ''; + echo $list; + ?> +
+ + + +
+ +
+ +
    
  +
+ + +
+
 
 
+
+ + diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/SaveTicket.php b/oss/vtiger/trunk/customerportal/HelpDesk/SaveTicket.php new file mode 100644 index 00000000..ce290bc9 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/SaveTicket.php @@ -0,0 +1,88 @@ +'title', + 'productid'=>'productid', + 'description'=>'description', + 'priority'=>'priority', + 'category'=>'category', + 'owner'=>'owner', + 'module'=>'module' + ); + +foreach($ticket as $key => $val) + $ticket[$key] = $_REQUEST[$key]; + +$ticket['owner'] = $username; +$ticket['productid'] = $_SESSION['combolist'][0]['productid'][$ticket['productid']]; + + +$title = $_REQUEST['title']; +$description = $_REQUEST['description']; +$priority = $_REQUEST['priority']; +$severity = $_REQUEST['severity']; +$category = $_REQUEST['category']; +$parent_id = $_SESSION['customer_id']; +$productid = $_SESSION['combolist'][0]['productid'][$_REQUEST['productid']]; + +$module = $_REQUEST['ticket_module']; + +$customerid = $_SESSION['customer_id']; +$sessionid = $_SESSION['customer_sessionid']; +$serviceid = $_REQUEST['servicename']; + +$params = Array(Array( + 'id'=>"$customerid", + 'sessionid'=>"$sessionid", + 'title'=>"$title", + 'description'=>"$description", + 'priority'=>"$priority", + 'severity'=>"$severity", + 'category'=>"$category", + 'user_name' => "$username", + 'parent_id'=>"$parent_id", + 'product_id'=>"$productid", + 'module'=>"$module", + 'assigned_to'=>"$Ticket_Assigned_to", + 'serviceid'=>"$serviceid" + )); + +$record_result = $client->call('create_ticket', $params); +if(isset($record_result[0]['new_ticket']) && $record_result[0]['new_ticket']['ticketid'] != '') +{ + $new_record = 1; + $ticketid = $record_result[0]['new_ticket']['ticketid']; +} + +if($new_record == 1) +{ + ?> + + diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/SearchForm.php b/oss/vtiger/trunk/customerportal/HelpDesk/SearchForm.php new file mode 100644 index 00000000..14dc62ab --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/SearchForm.php @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+  
+ +
 
diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/TicketDetail.php b/oss/vtiger/trunk/customerportal/HelpDesk/TicketDetail.php new file mode 100644 index 00000000..c95be2f8 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/TicketDetail.php @@ -0,0 +1,247 @@ + + + + + +     + + + + + "$ticketid", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + '.getTranslatedString('LBL_NOT_AUTHORISED').' + '; + include("footer.html"); + die(); + } + $ticketinfo = $result[0][$block]; + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'ticketid' => "$ticketid")); + $commentresult = $client->call('get_ticket_comments', $params, $Server_Path, $Server_Path); + $ticketscount = count($result); + $commentscount = count($commentresult); + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'ticketid' => "$ticketid")); + + //Get the creator of this ticket + $creator = $client->call('get_ticket_creator', $params, $Server_Path, $Server_Path); + + $ticket_status = ''; + foreach($ticketinfo as $key=>$value) { + $fieldlabel = $value['fieldlabel']; + $fieldvalue = $value['fieldvalue']; + if ($fieldlabel == 'Status') { + $ticket_status = $fieldvalue; + break; + } + } + //If the ticket is created by this customer and status is not Closed then allow him to Close this ticket otherwise not + if ($ticket_status != 'Closed' && $ticket_status != '') { + $ticket_close_link = ''.getTranslatedString('LBL_CLOSE_TICKET').'   '; + } else { + $ticket_close_link = ''; + } + + echo getblock_header('Ticket Information','4',$ticket_close_link); + echo getblock_fieldlist($ticketinfo); + + if($commentscount >= 1 && is_array($commentresult)) + { + + $list .= ' + '.getTranslatedString('LBL_TICKET_COMMENTS').' + + +
+ '; + + //Form the comments in between tr tags + for($j=0;$j<$commentscount;$j++) + { + $list .= ' + + + + '; + } + + $list .= ' +
'.($commentscount-$j).''.$commentresult[$j]['comments'].'
'.getTranslatedString('LBL_COMMENT_BY').' : '.$commentresult[$j]['owner'].' '.getTranslatedString('LBL_ON').' '.$commentresult[$j]['createdtime'].'
+
+ + '; + } + + + if($ticket_status != 'Closed') + { + $list .= ' + '.getTranslatedString('LBL_ADD_COMMENT').' +
+ + + + + + + + + +
+   +   + '; + } + $files_array = getTicketAttachmentsList($ticketid); + if($files_array[0] != "#MODULE INACTIVE#"){ + $list .= ' + + +   + '.getTranslatedString('LBL_ATTACHMENTS').''; + + //Get the attachments list and form in the tr tag + $attachments_count = count($files_array); + if(is_array($files_array)) + { + for($j=0;$j<$attachments_count;$j++) + { + $filename = $files_array[$j]['filename']; + $filetype = $files_array[$j]['filetype']; + $filesize = $files_array[$j]['filesize']; + $fileid = $files_array[$j]['fileid']; + $filelocationtype = $files_array[$j]['filelocationtype']; + //To display the attachments title + $attachments_title = ''; + if($j == 0) + $attachments_title = ''.getTranslatedString('LBL_ATTACHMENTS').''; + if($filelocationtype == 'I'){ + $list .= ' + + '.$attachments_title.' + '.ltrim($filename,$ticketid.'_').' + '; + }else { + $list .='' . + ''.$attachments_title.'' . + ''.$filename.'' . + ''; + } + } + } + else{ + $list .= ''.getTranslatedString('NO_ATTACHMENTS').''; + } + } + //To display the file upload error + if($upload_status != '') + { + $list .= ' + '.getTranslatedString('LBL_FILE_UPLOADERROR').' + '.$upload_status.' + '; + + } + + //Provide the Add Comment option if the ticket is not Closed + if($ticket_status != 'Closed' && $files_array[0] != "#MODULE INACTIVE#") + { + //To display the File Browse option to upload attachment + $list .= ' + +
+ + + + + '.getTranslatedString('LBL_ATTACH_FILE').' + + + +
+ '; + } + + $list .= ' + + + + + + +'; + + + echo $list; + echo ''; + echo ''; + echo ''; + +} +else + echo getTranslatedString('LBL_NONE_SUBMITTED'); + + +$filevalidation_script = << + +function getFileNameOnly(filename) { + var onlyfilename = filename; + // Normalize the path (to make sure we use the same path separator) + var filename_normalized = filename.replace(/\\\\/g, '/'); + if(filename_normalized.lastIndexOf("/") != -1) { + onlyfilename = filename_normalized.substring(filename_normalized.lastIndexOf("/") + 1); + } + return onlyfilename; +} +/* Function to validate the filename */ +function validateFilename(form_ele) { +if (form_ele.value == '') return true; + var value = getFileNameOnly(form_ele.value); + // Color highlighting logic + var err_bg_color = "#FFAA22"; + if (typeof(form_ele.bgcolor) == "undefined") { + form_ele.bgcolor = form_ele.style.backgroundColor; + } + // Validation starts here + var valid = true; + /* Filename length is constrained to 255 at database level */ + if (value.length > 255) { + alert(alert_arr.LBL_FILENAME_LENGTH_EXCEED_ERR); + valid = false; + } + if (!valid) { + form_ele.style.backgroundColor = err_bg_color; + return false; + } + form_ele.style.backgroundColor = form_ele.bgcolor; + form_ele.form[form_ele.name + '_hidden'].value = value; + return true; +} + +JSFILEVALIDATION; + +echo $filevalidation_script; +?> \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/TicketSearch.php b/oss/vtiger/trunk/customerportal/HelpDesk/TicketSearch.php new file mode 100644 index 00000000..50ca2b9b --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/TicketSearch.php @@ -0,0 +1,40 @@ + diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/TicketsList.php b/oss/vtiger/trunk/customerportal/HelpDesk/TicketsList.php new file mode 100644 index 00000000..92295b2e --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/TicketsList.php @@ -0,0 +1,167 @@ + + +   + + call('show_all',array('module'=>'HelpDesk'), $Server_Path, $Server_Path); + if($show == 'true'){ + echo '  '; + } + ?> + +     + + + + + +   + + + + +'; + $list .= ''; + $list .= '
'.getTranslatedString('LBL_NONE_SUBMITTED').'
'; + $list .= ''; +} else { + + $header = $result[0]['head'][0]; + $nooffields = count($header); + $data = $result[1]['data']; + $rowcount = count($data); + $showstatus = $_REQUEST['showstatus']; + if($showstatus != '' && $rowcount >= 1) { + $list .= '
'; + $list .= ''; + $list .= '
'.getTranslatedString($showstatus)." ".getTranslatedString('LBL_TICKETS').'
'; + $list .= ''; + $list .= ''; + + for($i=0; $i<$nooffields; $i++) + { + $header_value = $header[$i]['fielddata']; + $list .= ''; + } + $list .= ''; + + $ticketexist = 0; + for($i=0;$i'; + if ($header[$j]['fielddata'] == 'Status') { + $ticket_status = $data[$i][$j]['fielddata']; + } + } + $ticketlist .= ''; + + if($ticket_status == $showstatus){ + $list .= $ticketlist; + $ticketexist++; + } + } + if($ticketexist == 0) + { + $list .= ''; + } + + $list .= '
'.$header_value.'
 
'.getTranslatedString('LBL_NONE_SUBMITTED').'
'; + + } + else { + $list .= '
'; + $list .= ''; + $list .= '
'.getTranslatedString('LBL_MY_OPEN_TICKETS').'
'; + $list .= ''; + $list .= ''; + + $closedlist .= '
'; + $closedlist .= '
'.getTranslatedString('LBL_CLOSED_TICKETS').'
'; + $closedlist .= ''; + $closedlist .= ''; + + for($i=0; $i<$nooffields; $i++) + { + $header_value = $header[$i]['fielddata']; + $headerlist .= ''; + } + $headerlist .= ''; + + $list .= $headerlist; + $closedlist .= $headerlist; + + for($i=0;$i'; + if ($header[$j]['fielddata'] == 'Status') { + $ticket_status = $data[$i][$j]['fielddata']; + } + } + $ticketlist .= ''; + + if($ticket_status == getTranslatedString('LBL_STATUS_CLOSED')) + $closedlist .= $ticketlist; + elseif($ticket_status != '') + $list .= $ticketlist; + } + + $list .= '
'.getTranslatedString($header_value).'
'; + $closedlist .= ''; + + $closedlist .= '
'; + + $list .= '

'.$closedlist; + } +} +echo $list; + +?> diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/Utils.php b/oss/vtiger/trunk/customerportal/HelpDesk/Utils.php new file mode 100644 index 00000000..9364739e --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/Utils.php @@ -0,0 +1,227 @@ +'; + + //Add the default value as a first option + if($defaultval != '') + $list .= ''; + + foreach($value as $index => $val) + { + $selected = ''; + if($selectval == $val) + $selected = ' selected '; + $list .= ''; + } + $list .= ''; + + return $list; +} + +function UpdateComment() +{ + global $client,$Server_Path; + $ticketid = $_REQUEST['ticketid']; + $ownerid = $_SESSION['customer_id']; + $comments = $_REQUEST['comments']; + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'ticketid'=>"$ticketid",'ownerid'=>"$customerid",'comments'=>"$comments")); + + $commentresult = $client->call('update_ticket_comment', $params, $Server_Path, $Server_Path); +} + +function Close_Ticket($ticketid) +{ + global $client,$Server_Path; + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'ticketid'=>"$ticketid")); + + $result = $client->call('close_current_ticket', $params, $Server_Path, $Server_Path); + return $result; +} + +function getPicklist($picklist_name) +{ + + // Static cache to re-use information + static $_picklist_cache = array(); + if(isset($_picklist_cache[$picklist_name])) { + return $_picklist_cache[$picklist_name]; + } + + global $client,$Server_Path; + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'picklist_name'=>"$picklist_name")); + $ticket_picklist_array = $client->call('get_picklists', $params, $Server_Path, $Server_Path); + + // Save the result for re-use + $_picklist_cache[$picklist_name] = $ticket_picklist_array; + + return $ticket_picklist_array; +} + +function getStatusComboList($selectedvalue='') +{ + $temp_array = getPicklist('ticketstatus'); + + $status_combo = ""; + foreach($temp_array as $index => $val) + { + $select = ''; + if($val == $selectedvalue) + $select = ' selected'; + + $status_combo .= ''; + } + + return $status_combo; +} + +//Added for My Settings - Save Password +function SavePassword($version) +{ + global $client; + + $customer_id = $_SESSION['customer_id']; + $customer_name = $_SESSION['customer_name']; + $oldpw = trim($_REQUEST['old_password']); + $newpw = trim($_REQUEST['new_password']); + $confirmpw = trim($_REQUEST['confirm_password']); + + $params = Array('user_name'=>"$customer_name",'user_password'=>"$oldpw",'version'=>"$version",'login'=>'false'); + $result = $client->call('authenticate_user',$params); + $sessionid = $_SESSION['customer_sessionid']; + if($oldpw == $result[0]['user_password']) + { + if(strcasecmp($newpw,$confirmpw) == 0) + { + $customerid = $result[0]['id']; + + // $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'username'=>"$customer_name",'password'=>"$newpw",'version'=>"$version")); + + $result_change_password = $client->call('change_password',$params); + if($result_change_password[0] == 'MORE_THAN_ONE_USER'){ + $errormsg .= getTranslatedString('MORE_THAN_ONE_USER'); + }else{ + $errormsg .= getTranslatedString('MSG_PASSWORD_CHANGED'); + } + } + else + { + $errormsg .= getTranslatedString('MSG_ENTER_NEW_PASSWORDS_SAME'); + } + }elseif($result[0] == 'INVALID_USERNAME_OR_PASSWORD') { + $errormsg .= getTranslatedString('LBL_ENTER_VALID_USER'); + }elseif($result[0] == 'MORE_THAN_ONE_USER'){ + $errormsg .= getTranslatedString('MORE_THAN_ONE_USER'); + } + else + { + $errormsg .= getTranslatedString('MSG_YOUR_PASSWORD_WRONG'); + } + + return $errormsg; +} + +function getTicketAttachmentsList($ticketid) +{ + global $client; + + $customer_name = $_SESSION['customer_name']; + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + $params = Array(Array('id'=>"$customerid", 'sessionid'=>"$sessionid", 'ticketid'=>"$ticketid")); + $result = $client->call('get_ticket_attachments',$params); + + return $result; +} + +function AddAttachment() +{ + global $client, $Server_Path; + $ticketid = $_REQUEST['ticketid']; + $ownerid = $_SESSION['customer_id']; + + $filename = $_FILES['customerfile']['name']; + $filetype = $_FILES['customerfile']['type']; + $filesize = $_FILES['customerfile']['size']; + $fileerror = $_FILES['customerfile']['error']; + if (isset($_REQUEST['customerfile_hidden'])) { + $filename = $_REQUEST['customerfile_hidden']; + } + + $upload_error = ''; + if($fileerror == 4) + { + $upload_error = getTranslatedString('LBL_GIVE_VALID_FILE'); + } + elseif($fileerror == 2) + { + $upload_error = getTranslatedString('LBL_UPLOAD_FILE_LARGE'); + } + elseif($fileerror == 3) + { + $upload_error = getTranslatedString('LBL_PROBLEM_UPLOAD'); + } + + //Copy the file in temp and then read and pass the contents of the file as a string to db + global $upload_dir; + if(!is_dir($upload_dir)) { + echo getTranslatedString('LBL_NOTSET_UPLOAD_DIR'); + exit; + } + if($filesize > 0) + { + if(move_uploaded_file($_FILES["customerfile"]["tmp_name"],$upload_dir.'/'.$filename)) + { + $filecontents = base64_encode(fread(fopen($upload_dir.'/'.$filename, "r"), $filesize)); + } + + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + $params = Array(Array( + 'id'=>"$customerid", + 'sessionid'=>"$sessionid", + 'ticketid'=>"$ticketid", + 'filename'=>"$filename", + 'filetype'=>"$filetype", + 'filesize'=>"$filesize", + 'filecontents'=>"$filecontents" + )); + if($filecontents != ''){ + $commentresult = $client->call('add_ticket_attachment', $params, $Server_Path, $Server_Path); + }else{ + echo getTranslatedString('LBL_FILE_HAS_NO_CONTENTS'); + exit(); + } + } + else + { + $upload_error = getTranslatedString('LBL_UPLOAD_VALID_FILE'); + } + + return $upload_error; +} + +?> diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/index.html b/oss/vtiger/trunk/customerportal/HelpDesk/index.html new file mode 100644 index 00000000..45edcc59 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/index.html @@ -0,0 +1,64 @@ + + + + + + + + +
+ + + + + + +
+ + + +
 
+ + + + + + + + diff --git a/oss/vtiger/trunk/customerportal/HelpDesk/index.php b/oss/vtiger/trunk/customerportal/HelpDesk/index.php new file mode 100644 index 00000000..03bbb78b --- /dev/null +++ b/oss/vtiger/trunk/customerportal/HelpDesk/index.php @@ -0,0 +1,89 @@ +"$customerid", 'sessionid'=>"$sessionid", 'user_name' => "$username", 'onlymine' => $onlymine, 'where' => "$where", 'match' => "$match_condition")); + $result = $client->call('get_tickets_list', $params, $Server_Path, $Server_Path); + include("TicketsList.php"); +} +elseif($_REQUEST['fun'] == 'newticket') +{ + include("NewTicket.php"); +} +elseif($_REQUEST['fun'] == 'updatecomment' || $_REQUEST['fun'] == 'close_ticket' || $_REQUEST['fun'] == 'uploadfile') +{ + if($_REQUEST['fun'] == 'updatecomment') + { + UpdateComment(); + } + if($_REQUEST['fun'] == 'close_ticket') + { + $ticketid = $_REQUEST['ticketid']; + $res = Close_Ticket($ticketid); + } + if($_REQUEST['fun'] == 'uploadfile') + { + $upload_status = AddAttachment(); + if($upload_status != ''){ + echo $upload_status; + exit(0); + } + } + + ?> + +
'; +?> diff --git a/oss/vtiger/trunk/customerportal/INSTALLATION.txt b/oss/vtiger/trunk/customerportal/INSTALLATION.txt new file mode 100644 index 00000000..e9394352 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/INSTALLATION.txt @@ -0,0 +1 @@ +Please look at http://wiki.vtiger.com for more details. \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/Invoice/InvoiceDetail.php b/oss/vtiger/trunk/customerportal/Invoice/InvoiceDetail.php new file mode 100644 index 00000000..263b4863 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Invoice/InvoiceDetail.php @@ -0,0 +1,41 @@ +'; +$customerid = $_SESSION['customer_id']; +$sessionid = $_SESSION['customer_sessionid']; +if($id != '') +{ + + //Get the Basic Information + $block = "Invoice"; + $params = array('id' => "$id", 'block'=>"$block", 'contactid'=>"$customerid",'sessionid'=>"$sessionid"); + $result = $client->call('get_invoice_detail', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo '
'.getTranslatedString('LBL_NOT_AUTHORISED').'
'; + die(); + } + $invinfo = $result[0][$block]; + echo '
'; + echo getblock_fieldlist($invinfo); + echo ''; + echo '
'; + echo ''; + echo ''; + +} +?> diff --git a/oss/vtiger/trunk/customerportal/Invoice/InvoiceList.php b/oss/vtiger/trunk/customerportal/Invoice/InvoiceList.php new file mode 100644 index 00000000..a28827e2 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Invoice/InvoiceList.php @@ -0,0 +1,46 @@ + + '.getTranslatedString("LBL_INVOICE_INFORMATION").''; + $allow_all = $client->call('show_all',array('module'=>'Invoice'),$Server_Path, $Server_Path); + if($allow_all == 'true'){ + echo ' '.getTranslatedString('SHOW').'  '; + } + + echo '
+ '; + +if ($customerid != '' ) +{ + $block = "Invoice"; + $params = array('id' => "$customerid", 'block'=>"$block",'sessionid'=>$sessionid,'onlymine'=>$onlymine); + $result = $client->call('get_list_values', $params, $Server_Path, $Server_Path); + echo getblock_fieldlistview($result,$block); +} + + +?> diff --git a/oss/vtiger/trunk/customerportal/Invoice/index.html b/oss/vtiger/trunk/customerportal/Invoice/index.html new file mode 100644 index 00000000..c7f7620a --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Invoice/index.html @@ -0,0 +1,28 @@ + + +
+ +
+ + + + + + +
+ + + + + + diff --git a/oss/vtiger/trunk/customerportal/Invoice/index.php b/oss/vtiger/trunk/customerportal/Invoice/index.php new file mode 100644 index 00000000..121d0bb5 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Invoice/index.php @@ -0,0 +1,66 @@ + "$id", 'block'=>"$block", 'contactid'=>"$customerid",'sessionid'=>"$sessionid"); + $filecontent = $client->call('get_pdf', $params, $Server_Path, $Server_Path); + if($filecontent != 'failure') + { + $filename="$Server_Path/test/product/".$id."_Invoice.pdf"; + header("Content-type: text/pdf"); + header("Cache-Control: private"); + header("Content-Disposition: attachment; filename=$filename"); + header("Content-Description: PHP Generated Data"); + echo base64_decode($filecontent); + + exit; + + } + else + { + echo getTranslatedString('LBL_PDF_CANNOT_GENERATE');//We have to show the error message like "PDF output cannot be generated. Please contact admin" + } + } + else + { + include("InvoiceDetail.php"); + } + + } + else + { + include("InvoiceList.php"); + echo '
'; + } + + +?> + + \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/LICENSE_AGREEMENT.txt b/oss/vtiger/trunk/customerportal/LICENSE_AGREEMENT.txt new file mode 100644 index 00000000..49b53f81 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/LICENSE_AGREEMENT.txt @@ -0,0 +1,173 @@ +The vtiger Public License Version 1.0 is based on the Mozilla Public License Version 1.1 + +vtiger Public License +Version 1.0 + +Copyright (c) 2004 www.vtiger.com All rights reserved. + +PLEASE READ THE FOLLOWING LICENSE AGREEMENT CAREFULLY. ANY USE OF SOFTWARE DOWNLOADED OR ORDERED FROM VTIGER IS PERMITTED ONLY UNDER LICENSE WITH VTIGER. BY DOWNLOADING THIS SOFTWARE YOU AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE AGREEMENT. + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. + + 1.1. ''Contributor'' means each entity that creates or contributes to the creation of Modifications. + + 1.2. ''Contributor Version'' means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. + + 1.3. ''Covered Code'' means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. + + 1.4. ''Electronic Distribution Mechanism'' means a mechanism generally accepted in the software development community for the electronic transfer of data. + + 1.5. ''Executable'' means Covered Code in any form other than Source Code. + + 1.6. ''Initial Developer'' means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. + + 1.7. ''Larger Work'' means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. + + 1.8. ''License'' means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. ''Modifications'' means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: + A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or previous Modifications. + + 1.10. ''Original Code'' means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.11. ''Source Code'' means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. + + 1.12. "You'' (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You'' includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control'' means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. Source Code License. + + 2.1.The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). + (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. + + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL'' which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. + + (b)Contributor APIs. + If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. + + (c)Representations. + Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. + + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + +If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. + +5. Application of this License. + +This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation (''Netscape'') may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases ''vtiger'', ''vtigerPL'', ''MOZPL'', ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the vtiger Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) + +7. DISCLAIMER OF WARRANTY. + +COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. + + 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + +The Covered Code is a ''commercial item,'' as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and ''commercial computer software documentation,'' as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. + +11. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. + +12. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + +Initial Developer may designate portions of the Covered Code as “Multiple-Licensed”. “Multiple-Licensed” means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the MPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. + + +EXHIBIT A -vtiger Public License. + +"The contents of this file are subject to the vtiger Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License." + +Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. + +The Original Code is vtiger Outlook Plug-in. + +The Initial Developer of the Original Code is vtiger. Portions created by vtiger are Copyright (C) www.vtiger.com. All Rights Reserved. + +Contributor(s): ______________________________________. + + [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] + + + + diff --git a/oss/vtiger/trunk/customerportal/MySettings.php b/oss/vtiger/trunk/customerportal/MySettings.php new file mode 100644 index 00000000..1e74e156 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/MySettings.php @@ -0,0 +1,165 @@ + + + + + + My Settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
 
+ +
+ +
+ +
 
+    + +
 
+ + + + + + diff --git a/oss/vtiger/trunk/customerportal/PortalConfig.php b/oss/vtiger/trunk/customerportal/PortalConfig.php new file mode 100644 index 00000000..c8171f44 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/PortalConfig.php @@ -0,0 +1,40 @@ +'US English'); + +?> diff --git a/oss/vtiger/trunk/customerportal/Products/ProductDetail.php b/oss/vtiger/trunk/customerportal/Products/ProductDetail.php new file mode 100644 index 00000000..e6344609 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Products/ProductDetail.php @@ -0,0 +1,38 @@ + "$productid", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + '.getTranslatedString('LBL_NOT_AUTHORISED').' + '; + die(); + } + $noteinfo = $result[0][$block]; + echo '
'; + echo getblock_fieldlist($noteinfo); + + echo ''; + echo ''; + echo ''; + +} + +?> diff --git a/oss/vtiger/trunk/customerportal/Products/ProductList.php b/oss/vtiger/trunk/customerportal/Products/ProductList.php new file mode 100644 index 00000000..da017c44 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Products/ProductList.php @@ -0,0 +1,54 @@ +$customerid,'block'=>$block,'sessionid'=>$sessionid,'onlymine'=>$onlymine); + $result = $client->call('get_product_list_values', $params, $Server_Path, $Server_Path); + + echo ' + '.getTranslatedString("LBL_PRODUCT_INFORMATION").''; + $allow_all = $client->call('show_all',array('module'=>'Products'),$Server_Path, $Server_Path); + + if($allow_all == 'true'){ + echo ' '.getTranslatedString('SHOW').'  '; + } + + echo '
+ ';; + + echo getblock_fieldlistview_product($result,$block); + echo '
'; +echo ''; + + +?> + + + + diff --git a/oss/vtiger/trunk/customerportal/Products/index.html b/oss/vtiger/trunk/customerportal/Products/index.html new file mode 100644 index 00000000..34a645c9 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Products/index.html @@ -0,0 +1,23 @@ + + + + +
+ + + + + + + + +
+ diff --git a/oss/vtiger/trunk/customerportal/Products/index.php b/oss/vtiger/trunk/customerportal/Products/index.php new file mode 100644 index 00000000..d38bbd09 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Products/index.php @@ -0,0 +1,32 @@ + diff --git a/oss/vtiger/trunk/customerportal/Quotes/QuoteDetail.php b/oss/vtiger/trunk/customerportal/Quotes/QuoteDetail.php new file mode 100644 index 00000000..67b51bd5 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Quotes/QuoteDetail.php @@ -0,0 +1,39 @@ + "$quote_id", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo '
'.getTranslatedString('LBL_NOT_AUTHORISED').'
'; + die(); + } + $quoteinfo = $result[0][$block]; + echo '
'; + echo getblock_fieldlist($quoteinfo); + echo ''; + echo ''; + echo ''; + +} +else + print_r("no quote"); +?> diff --git a/oss/vtiger/trunk/customerportal/Quotes/QuotesList.php b/oss/vtiger/trunk/customerportal/Quotes/QuotesList.php new file mode 100644 index 00000000..bd93d81f --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Quotes/QuotesList.php @@ -0,0 +1,58 @@ + + '.getTranslatedString("LBL_QUOTE_INFORMATION").''; + $allow_all = $client->call('show_all',array('module'=>'Quotes'),$Server_Path, $Server_Path); + + if($allow_all == 'true'){ + echo ' '.getTranslatedString('SHOW').'  '; + } + + echo '
+ '; + + + $block = "Quotes"; + $sessionid = $_SESSION['customer_sessionid']; + $params = array('id' => "$customerid", 'block'=>"$block",'sessionid'=>"$sessionid",'onlymine'=>$onlymine); + $result = $client->call('get_list_values', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + +
'.getTranslatedString('LBL_NOT_AUTHORISED').'
'; + die(); + } + + echo getblock_fieldlistview($result,$block); +} + + +?> diff --git a/oss/vtiger/trunk/customerportal/Quotes/index.html b/oss/vtiger/trunk/customerportal/Quotes/index.html new file mode 100644 index 00000000..c7f7620a --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Quotes/index.html @@ -0,0 +1,28 @@ + + + + +
+ + + + + + +
+ + + + + + diff --git a/oss/vtiger/trunk/customerportal/Quotes/index.php b/oss/vtiger/trunk/customerportal/Quotes/index.php new file mode 100644 index 00000000..e2aff484 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Quotes/index.php @@ -0,0 +1,40 @@ +
'; + +?> + + + diff --git a/oss/vtiger/trunk/customerportal/Services/ServiceDetail.php b/oss/vtiger/trunk/customerportal/Services/ServiceDetail.php new file mode 100644 index 00000000..d9902607 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Services/ServiceDetail.php @@ -0,0 +1,39 @@ + "$serviceid", 'block'=>"$block",'contactid'=>$customerid,'sessionid'=>"$sessionid"); + $result = $client->call('get_details', $params, $Server_Path, $Server_Path); + // Check for Authorization + if (count($result) == 1 && $result[0] == "#NOT AUTHORIZED#") { + echo ' + '.getTranslatedString('LBL_NOT_AUTHORISED').' + '; + die(); + } + $serviceinfo = $result[0][$block]; + + echo '
'; + echo getblock_fieldlist($serviceinfo ); + echo ''; + echo ''; + echo ''; + +} +else + print_r("no quote"); +?> diff --git a/oss/vtiger/trunk/customerportal/Services/ServiceList.php b/oss/vtiger/trunk/customerportal/Services/ServiceList.php new file mode 100644 index 00000000..396bef67 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Services/ServiceList.php @@ -0,0 +1,51 @@ +$customerid,'module'=>$module,'sessionid'=>$sessionid,'onlymine'=>$onlymine); + $result = $client->call('get_service_list_values', $params, $Server_Path, $Server_Path); + + echo ' + '.getTranslatedString("LBL_SERVICE").''; + $allow_all = $client->call('show_all',array('module'=>$module),$Server_Path, $Server_Path); + + if($allow_all == 'true'){ + echo ' '.getTranslatedString('SHOW').'  '; + } + + echo '
+ ';; + + echo getblock_fieldlistview_product($result,$module); + echo '
'; +echo ''; + + +?> diff --git a/oss/vtiger/trunk/customerportal/Services/index.html b/oss/vtiger/trunk/customerportal/Services/index.html new file mode 100644 index 00000000..c7f7620a --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Services/index.html @@ -0,0 +1,28 @@ + + + + +
+ + + + + + +
+ + + + + + diff --git a/oss/vtiger/trunk/customerportal/Services/index.php b/oss/vtiger/trunk/customerportal/Services/index.php new file mode 100644 index 00000000..619a2a15 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/Services/index.php @@ -0,0 +1,40 @@ +
'; + +?> + + + diff --git a/oss/vtiger/trunk/customerportal/css/dropdown.css b/oss/vtiger/trunk/customerportal/css/dropdown.css new file mode 100644 index 00000000..2d20a7bb --- /dev/null +++ b/oss/vtiger/trunk/customerportal/css/dropdown.css @@ -0,0 +1,176 @@ +div.acinputContainer +{ + position: relative; + float: left; + width: 240px; + height: 20px; + margin:0px; + padding: 0px; + border-width: 1px; + border-style: solid; +/* border-color: buttonshadow buttonhighlight buttonhighlight buttonshadow;*/ + border-color: #aaa #eee #eee #aaa; + background-color: buttonface; + overflow: show; + box-sizing: border-box; + -moz-box-sizing: border-box; +} + +div.acinputContainer input +{ + position: relative; + float: left; + width: 220px; + height: 100%; + border-width: 1px; + margin:0px; + padding: 0px; + clear: none; + float: left; + box-sizing: border-box; + -moz-box-sizing: border-box; +} + +/* this is set when the input is 'working' i.e. remote loading is in process */ +div.acinputContainer input.search +{ + background-color: #b41b00; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +div.acinputContainer input.button +{ + position: relative; + float: left; + font-size: 2px; + width:18px; + height: 100%; + border-width: 1px; + background-image:url( ../i/arrowdown.gif ); + background-repeat: no-repeat; + background-position: 2px 2px; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +input.dropdown +{ + width: 160px; + border: 1px solid #AAAAAA; + border-color: #888 #aaa #aaa #888; + margin-bottom: 2px; + -moz-box-sizing : border-box; +} + +div.autocomplete_holder +{ + position: absolute; + visibility: hidden; + background-color: #fff; + background-image: url( ../i/bg.gif ); + -moz-box-sizing : border-box; +} + +div.autocomplete_firstborder +{ + border-width: 1px; + border-style: solid; + border-color: buttonshadow buttonhighlight buttonhighlight buttonshadow; + padding: 0px; + -moz-box-sizing : border-box; +} + +div.autocomplete_secondborder +{ + border-style: none; + padding: 2px; + -moz-box-sizing : border-box; +} + +ul.autocomplete +{ + width : 100%; + height : 95px; + overflow-y : auto; + overflow : -moz-scrollbars-vertical; + + font : menu; + + margin : 0px; + margin-left : 0px; + padding-left : 0px; + text-indent : 0px; + + list-style-type : none; + vertical-align : middle; + + background-repeat : no-repeat; + -moz-box-sizing : border-box; +} + +ul.autocomplete li a, ul.autocomplete li a:hover, +ul.autocomplete li a.selected, ul.autocomplete li a:hover.selected +{ + display : block; + width : 100%; + padding : 2px; + text-decoration : none; + color : #333; + border : 1px solid #fff; + -moz-box-sizing : border-box; + + margin-left : -14px; + voice-family : "\"}\""; + voice-family : inherit; + margin-left : 0px; +} + +ul.autocomplete li +{ + padding : 0px; + paddnig-left : 5px; + background-position : 2px 0px; + background-repeat : no-repeat; + + line-height : 13px; + vertical-align : top; + margin : 0px; + /*border-style : none;*/ + -moz-box-sizing : border-box; +} + +ul.autocomplete li a +{ +} + +ul.autocomplete li a:hover +{ + color: highlighttext; + background-color: highlight; + border-color: #e0e0e0; +} + +ul.autocomplete li a.selected +{ + border : 1px solid #444; + /* + background-color : #fcbdb6; + color : #fff; + */ + background-color : #0d94df; + color : #fff; + + background-color: #f00; + background-image: url( ../i/conf.gif ); + background-position: center right; + background-repeat: no-repeat; +} + +ul.autocomplete li a:hover.selected +{ + border : 1px solid #e0e0e0; + color : white; + background-color : #f00; + background-image: none; +} diff --git a/oss/vtiger/trunk/customerportal/css/style.css b/oss/vtiger/trunk/customerportal/css/style.css new file mode 100644 index 00000000..71239b8d --- /dev/null +++ b/oss/vtiger/trunk/customerportal/css/style.css @@ -0,0 +1,904 @@ +/* CSS Document */ + +body{ + margin:0 0 0 0; + font-size:12px; + font-family:Verdana, Arial, Helvetica, sans-serif; +} + +body tr td{ + font-size:12px; + font-family:Verdana, Arial, Helvetica, sans-serif; +} +.outerTab{ + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:11px; + text-align:left; + width:100%; + border:0px solid #999999; +} + +.innerTab{ + width:100%; + border:0px; +} + +.innerTab tr th{ + background-image:url(../images/loginTopBg.gif); +} + +.tableTop{ + background-image:url(../images/loginTopShade.gif); + height:10px; + background-repeat:repeat-x; + background-position:top; +} + +.tableMid{ + background-image:url(../images/loginBgbig.jpg); + background-repeat:repeat-x; + background-position:top; + height:518px; + vertical-align:middle; + text-align:center; +} + +.tableMidone{ + background-image:url(../images/loginBgbig.jpg); + background-repeat:repeat-x; + background-position:top; + height:400px; + vertical-align:middle; + text-align:center; +} + +.tableBtm{ + background-image:url(../images/loginBottomBg.gif); + background-repeat:repeat-x; + background-position:top; + height:13px; +} + +.loginTab{ + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:11px; + text-align:left; + border:0px; + width:50%; +} +.dvtLabel td{ + background-color:#f6f6f6; + padding-left:5px; + padding-right:5px; + border-right:1px solid #eaeaea; + border-bottom:1px solid #eaeaea; + color:#737373; + height:25px; + text-align:left; + font-size:11px; +} + +.dvtInfo td { + padding-left:5px; + padding-right:5px; + border-bottom:1px solid #eaeaea; + border-right:1px solid #eaeaea; + height:25px; + text-align:left; + font-size:11px; +} + +#scrollTab{ + position:relative; + width:100%; + height:350px; + overflow:auto; + border:0px solid #CCCCCC; + display:block; +} + +#scrollTab1{ + position:relative; + width:100%; + height:372px; + overflow:auto; + border:0px solid #CCCCCC; + display:block; +} + +#scrollTab2{ + position:relative; + width:98%; + height:175px; + overflow:auto; + border:0px solid #CCCCCC; + display:block; +} + +.hdr{ + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:10px; + font-weight:normal; + text-decoration:none; + color:#666666; +} + + +a.hdr,a.hdr:Hover{ + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:10px; + font-weight:normal; + text-decoration:underline; + color:#666666; +} + +.small { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + line-height: 14px; + color: #000000; + background-color: #ADAAAD; +} +.big { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + line-height: 18px; + color: #aaaaaa; + font-weight:bold; +} +.genHeaderBig{ + font-family: Arial, Helvetica, sans-serif; + font-size: 16px; + line-height: 19px; + color: #000000; + font-weight:bold; +} +.genHeaderSmall{ + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + line-height: 16px; + color: #000000; + font-weight:bold; +} + +.moduleName { + font-family: Arial, Helvetica, sans-serif; + font-size: 18px; + color: #000000; + font-weight:bold; +} + +.rssDisplayPanel { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + line-height: 12px; + color: #ABABAB; +} +.hdrNameBg { + + background:url(images/topBg.gif); +} + +.hdrTabBg { + background:#bbbbbb url(images/tabUnSelectedBg.gif) repeat-x ; +} + +.tabSelected { + background:#bbbbbb url(images/tabSelectedBg.gif) repeat-x; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding-left:15px; + padding-right:15px; + padding-top:2px; + padding-bottom:2px; + +} + +.tabUnSelected { + background:#bbbbbb url(images/tabUnSelectedBg.gif) repeat-x; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding-left:15px; + padding-right:15px; + padding-top:2px; + padding-bottom:2px; +} + +.tabSeperator { + background:#bbbbbb url(images/tabSeperatorBg.gif) repeat-x; + + +} + +.level2text { + background:#bbbbbb url(images/level2Bg.gif) repeat-x; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding-left:20px; + padding-right:20px; + padding-top:5px; + padding-bottom:5px; + font-weight:bold; + color:white; +} + +.level2text a{ + text-decoration:none; + color:white; + +} + +.level2text a:hover { + text-decoration:underline; + color:white; + +} + + + +.level2Bg { + background:#bbbbbb url(images/level2Bg.gif) repeat-x; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + +} + +.tabLiner { + background:#9abffc url(images/moduleSelectorBg.gif) bottom repeat-x; + padding:0px; + + +} +.sep1 { + background:#999999; +} + + +.showPanelBg { + background:url(images/showPanelTopBg.gif) repeat-x; +} + +a { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + text-decoration:none; + color:#333366; + +} + +a:hover { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + text-decoration:underline; + color:#333333; + +} + +.hdrLink { + font-family: Arial, Helvetica, sans-serif; + font-size: 18px; + text-decoration:none; + color:#333333; + font-weight:bold; +} + + +.hdrLink:hover { + font-family: Arial, Helvetica, sans-serif; + font-size: 18px; + text-decoration:underline; + color:#333333; + font-weight:bold; +} + + +.searchBox { + border: 0px solid #999999; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding-left:2px; + width:100px; + background-color:#ffffef; + +} +.searchBtn { + border : 1px #cccccc solid; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + width:30px; + height:19px; + background-color:#cccccc; +} + +.lvtBg { + background-color:#cccccc; + +} +.lvtHeaderText { + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + font-weight:bold; +} +.lvtCol { + border-top:1px solid #eeeeee; + border-left:1px solid #eeeeee; + border-right:1px solid #999999; + border-bottom:1px solid #999999; + background-color:#dadada; + color:#666666; + font-weight:bold; +} + +.lvtColData { + background-color:#fafafa; +} + +.lvtColDataHover { + background-color:#efefef; +} + +.dvtSelectedCell { + border-left:1px solid #cacaca; + border-top:3px solid #999999; + border-right:1px solid #cacaca; + padding-left:20px; + padding-right:20px; + background-color:white; + font-weight:bold; +} +.dvtUnSelectedCell { + border-left:1px solid #cacaca; + border-top:1px solid #cacaca; + border-right:1px solid #cacaca; + border-bottom:1px solid #cacaca; + padding-left:20px; + padding-right:20px; + background-color:#efefef; + cursor:pointer; +} +.dvtTabCache { + border-bottom:1px solid #cacaca; +} + +.dvtContentSpace { + border-left:1px solid #cacaca; + border-right:1px solid #cacaca; + border-bottom:1px solid #cacaca; + padding-left:0px; +} +.rightAddInfo { + border-left:1px solid #a2a2a2; + border-right:1px solid #dddddd; + border-bottom:1px solid #dddddd; + border-top:1px solid #a2a2a2; + background-color:#fafafa; + padding:5px; +} +.dvtCellLabel{ + background-color:#f6f6f6; + padding-right:10px; + border-bottom:1px solid #eaeaea; + color:#737373; +} + +.dvtCellInfo{ + padding-left:10px; + border-bottom:1px solid #eaeaea; +} + +.rightMailMerge { + border:1px solid #dddddd +} + +.rightMailMergeHeader { + border-bottom:1px solid #dddddd; + padding:5px; + font-size: 11px; + line-height: 14px; + background-color:#eaeaea; + +} + +.rightMailMergeContent { + padding:5px; + background-color:#fafafa; + +} + +.rightUpcomingActivitiesHeader{ + border-bottom:1px solid #ddddcc; + padding:5px; + background-color:#ffffdd; +} + +.rightUpcomingActivitiesContent { + padding:5px; + background-color:#ffffef; +} + +.detailedViewHeader{ + border-bottom:1px solid #999999; + border-right:1px solid #CCCCCC; + padding:5px; + background-color:#e5e5e5; + text-align:left; +} + +.detailedViewTextBox { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + color: #000000; + border:1px solid #bababa; + padding-left:5px; +/* width:85%; -- commented to fix, status not fully visible in search window*/ + background-color:#ffffff; +} +.detailedViewTextBoxOn { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + color: #000000; + border:1px solid #bababa; + padding-left:5px; + width:85%; + background-color:#ffffdd; +} +.detailedViewTextArea { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + color: #000000; + border:1px solid #bababa; + padding-left:5px; + width:95%; + height:100px; + background-color:#ffffff; + text-align:left; +} + +.moduleSearch { + border:1px solid #dddddd; + background-color:#ffffef; + +} +.searchHdrBox { + + border-bottom:1px dashed #dddddd; +} + +.advSearch { + padding:10px; + border-left:1px solid #eaeaea; + border-right:1px solid #eaeaea; + border-bottom:1px solid #eaeaea; + overflow:auto; + width:600px; + height:150px; + background-color:#ffffef; + +} +.searchAlph { + border:1px solid #dadada; + background-color:#ffffff; + width:10px + +} + +.searchNotFound { + border:2px solid #ff3333; + background-color:#fafafa; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #ff0000; + height:50px; + width:640px; + +} + +.hiliteBtn4Search { + border:1px solid #cccccc; + background-color:#fafafa; + line-height:37px; + height:40px; + padding:5px; +} + +.loginTopBg { + background:url(images/loginTopBg.gif) repeat-x; +} + +.loginTopShade { + background:url(images/loginTopShade.gif) repeat-x; +} + +.loginBg{ + background:#448cEB url(images/loginBg.gif) repeat-x; +} + +.textbox { + border:1px solid #999999; + background-color:#ffffff; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + width:120px; + padding:2px; + +} +.loginBottomBg { + background:url(images/loginBottomBg.gif) repeat-x; +} +.loginSignin { + font-family: Arial, Helvetica, sans-serif; + font-size: 18px; + color: #448ceb; + font-weight:bold; +} + +.loginBillBoard { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + color:#ffffff; +} + +.mx { +} + +.calTopBg { + background:url(images/calBg.gif) repeat-x; +} + +.calDisplay { + border-left:1px solid #d0d0d0; + border-right:1px solid #d0d0d0; +} +.calBottomBg { + background:url(images/calBottomBg.gif) repeat-x; +} + +.calDayHourCell { + font-family: Arial, Helvetica, sans-serif; + font-size: 18px; +} +.calDayHour { + border-top:2px solid #dadada; +} +.calDiv { + overflow:auto; width:95%;height:320px;padding:0px;background-color:#fefefe; + border-top: 1px solid #bababa; + border-bottom: 1px solid #bababa; + + +} + +.calHourOccupied { + background-color:#ffffbb; + +} + +.calAddEvent { + position:absolute; + z-index:1000000; + width:500px; + + left:200px; + top:150px; + border:2px solid #999999; + background-color:#ffffff; + padding:5px; +} + +.addEventHeader{ + border-bottom:2px dotted #cccccc; +} + +.addEventFooter{ + border-top:2px dotted #cccccc; + height:40px; +} + +.addEventInnerBox { + border:1px dotted #dadada; + +} + +.cellScheduled { + background-color:#ffffef; + color:#7a7a7a; + +} + +.cellSchHover { + border-bottom:1px solid #999999; + border-right:1px solid #999999; + border-left:1px solid #dadada; + border-top:1px solid #dadada; + background-color:#ffffef; + color:#7a7a7a; +} +.cellSch{ + border:0px; + background-color:#ffffef; + color:#7a7a7a; +} + + +.cellNormalHover { + border-bottom:1px solid #999999; + border-right:1px solid #999999; + border-left:1px solid #dadada; + border-top:1px solid #dadada; + background-color:#ffffff; + color:#7a7a7a; +} + +.cellNormal { + border:0px; + background-color:#ffffff; +} + +.calEventNormal { + border:1px solid #999999; + background-color:#99ffcc; + +} + +.calEventCritical { + border:1px solid #999999; + background-color:#FFCC33; +} +.tblPro1 { + +border:2px solid #dadada; + background-color:white; + + +} +.tblPro1IconCell { + border-right:1px solid #dadada; +} + +.tblPro1HeadingCell { + font-weight:bold; +color:#4a4a4a; +} + +.tblPro1ColHeader { + background-color:#dadada; + border-left:1px solid white; + border-right:1px solid #999999; + font-size: 11px; + line-height: 14px; + background-image:url(images/tblPro1ColBg.gif); +} +.tblPro1DataCell { + border-bottom:1px solid #f5f5f5; + color:#5a5a5a; + font-size: 11px; + line-height: 14px; + +} +.divEventToDo { +overflow:auto; +height:150px; +border:1px solid #dadada; + +} +.EventToDo{ + +} + +.addimage{ + text-align:left; + font-weight:bold; + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:12px; + color:#000000; + text-decoration:none; +} + +.toosmall{ + font-size:1px; + height:15px; + width:15px; + line-height:1px; + margin:0px; +} + +.bggray{ + background-color: #dfdfdf; +} +.bgwhite{ + background-color: #FFFFFF; +} +.copy{ + font-size:9px; + font-family: Verdana, Arial, Helvetica, Sans-serif; +} + +#mnuTab{ + position:relative; + overflow:auto; + width:100%; + display:block; + left:0px; + top:0px; + padding:0px; +} + +#mnuTab table tr td{ + padding:2px; +} + +#mnuTab2{ + position:relative; + overflow:auto; + width:100%; + display:none; +} + +.style1 {color: #FF0000} + +select{ + font-family:Arial, Helvetica, sans-serif; + font-size:12px; + border:1px solid #CCCCCC; +} + +.inputTxt{ + font-family:Arial, Helvetica, sans-serif; + font-size:12px; + border:1px solid #CCCCCC; + width:90%; +} + +#tabSrch{ + display:none; + width:700px; + border:0px; + position:absolute; + left:135px; + top:170px; + background-image:url(../images/loginBg.gif); + border:1px solid #CCCCCC; +} + +.mainTab{ + width:100%; + border-top:1px solid #CCCCCC;vertical-align:top; + height:450px; +} + +.mainTab tr td{border-right:1px solid #CCCCCC;vertical-align:top;} + +.tabLftMnu{ + width:100%; + border:0px; + display:none; +} + +.tabLftMnu tr td{ + padding-left:15px; + padding-right:5px; + padding-top:5px; + padding-bottom:5px; + border-right:0px solid #000000; +} + +.dummy tr td{ + padding-left:15px; + padding-right:0px; + padding-top:5px; + padding-bottom:5px; + border-right:0px solid #000000; +} + +.mnu{ + font-size:12px; + text-decoration:underline; + font-weight:bold; + color:#666666; + cursor:pointer; +} + +a.faqQues { + font-family:Arial, Helvetica, sans-serif; + font-size:11px; + font-weight:bold; + text-decoration:none; + color:#000066; +} + +a.faqQues:Hover { + font-family:Arial, Helvetica, sans-serif; + font-size:11px; + font-weight:bold; + text-decoration:underline; + color:#000066; +} + +.lnkHdr{ + font-family:Arial, Helvetica, Sans-serif; + font-size:11px; + font-weight:bold; + cursor:pointer; + text-decoration:underline; + vertical-align:bottom; +} + +#faqDetail{ + position:absolute; + width:250px; + /*height:110px; + overflow:hidden;*/ + border:1px solid #E5E5E5; + opacity: .9; + background-color:#F5F5F5; + left:685px;top:65px; + padding:5px; + visibility:hidden; +} + +.fagView{ + width:100%; + border:0px solid #000000; +} + +.fagView tr td{ + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:11px; + text-decoration:none; + padding:4px; + border-bottom:1px solid #F4F4F4; +} + +.lftMnu{ + width:100px; +} +.lftMnu tr td{ + padding-left:15px; + padding-right:0px; + padding-top:5px; + padding-bottom:5px; + border-right:0px solid #000000; + white-space:wrap; + text-align:left; +} + +#ticket_status_combo{ + font-size:11px; + font-weight:normal; +} + +#only_mine_combo{ + font-size:11px; + font-weight:normal; +} + +#settings{ + position:absolute; + display:block; + width:400px; + left:600px; + top:50px; + background-color:#FFFFFF; + border:2px solid #CCCCCC; +} + +.MySettingsHdr{ + font-family:Verdana, Arial, Helvetica, sans-serif; + font-size:10px; + font-weight:normal; + text-decoration:underline; + color:#666666; + cursor:pointer; +} + +.crmButton{ + border-left:1px solid #ffffff; + border-top:1px solid #ffffff; + border-right:1px solid #555555; + border-bottom:1px solid #555555; +} + +.cancel { + color:#fff; + font-weight:bold; +} diff --git a/oss/vtiger/trunk/customerportal/footer.html b/oss/vtiger/trunk/customerportal/footer.html new file mode 100644 index 00000000..c846e54b --- /dev/null +++ b/oss/vtiger/trunk/customerportal/footer.html @@ -0,0 +1,88 @@ + + + +
+ + + + + + + +   + +   + + + + +   + + + + + +
+ + + + + + + +
+ + + + + + +
+ +
+ + + + + diff --git a/oss/vtiger/trunk/customerportal/header.html b/oss/vtiger/trunk/customerportal/header.html new file mode 100644 index 00000000..79649268 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/header.html @@ -0,0 +1,97 @@ + + + + + +vtiger CRM 5 - CustomerPortal + + +'; +} +?> + + + + + + + + + + + + + + +
  +  |  +
+ + + + + + + + + + + + + +
 
  + + +
+ + + + + + + + '; + $list .=''; + } else { + $list .=''; + } + return $list; + +} + + +function getblock_fieldlist($block_array) +{ + $list='';$z=0; + $field_count=count($block_array); + if($field_count != 0) + { + for($i=0;$i<$field_count;$i++,$z++) + { + $blockname = $block_array[$i]['blockname']; + $data = $block_array[$i]['fieldvalue']; + if($block_array[$i]['fieldlabel'] == 'Note'){ + $data = html_entity_decode($data); + } + if($data =='') + $data =' '; + if(strcmp($blockname,$block_array[$i-1]['blockname'])){ + if($blockname != 'Ticket Information') //hardcoded for tickets information block so that it ll not be displayed + $list .= getblock_header($blockname); + $z = 0; + } + if($z==0 || $z%2==0) + $list .= ''; + $list .= ''; + if(($z == 0 || $z%2 == 0) &&($i == ($field_count-1))) + $list .= ''; + else + $list .= ''; + if($z%2 == 1 ||($i == ($field_count-1) )) + $list .= ''; + } + } + $list.= ''; + return $list; +} + +function getTranslatedString($str) +{ + global $app_strings; + return (isset($app_strings[$str]))?$app_strings[$str]:$str; +} + +// The function to get html format list data +// input array +// output htmlsource list array +//only for product +function getblock_fieldlistview_product($block_array,$module) +{ + + $header = array(); + $header[0] = getTranslatedString($module); + $header[1] = getTranslatedString('QUOTE_RELATED').getTranslatedString($module); + $header[2] = getTranslatedString('INVOICE_RELATED').getTranslatedString($module); + + if($block_array == '') + { + $list.=''; + return $list; + } + +for($k=0;$k<=2;$k++) +{ + +$header_arr =$block_array[$k][$module]['head'][0]; +$nooffields=count($header_arr); +$data_arr=$block_array[$k][$module]['data']; + $noofdata=count($data_arr); + $list.=getblock_header($header[$k],$nooffields); + if($block_array[$k][$module]['data'] == ''){ + $list.=''; + } + if($nooffields!='') + { + + $list .=''; + for($i=0;$i<$nooffields;$i++) + $list .= ""; + $list .=''; + } + if($noofdata != '') + { + for($j=0;$j<$noofdata;$j++) + { + if($j==0||$j%2==0) + $list .=''; + else + $list .=''; + + for($i=0;$i<$nooffields;$i++) + { + $data =$data_arr[$j][$i]['fielddata']; + if($data == '') + $data =' '; + $list .= ""; + } + $list .=''; + } + } + $list .= ''; +} +return $list; +} + +// The function to get html format list data +// input array +// output htmlsource list array +//for quotes,notes and invoice + +function getblock_fieldlistview($block_array,$block) +{ + if($block_array[0] == "#MODULE INACTIVE#"){ + $list.=''; + return $list; + } + if($block_array == ''){ + $list.=''; + return $list; + } + $header_arr =$block_array[0][$block]['head'][0]; + $nooffields=count($header_arr); + $data_arr=$block_array[1][$block]['data']; + $noofdata=count($data_arr); + if($nooffields!='') + { + $list .=''; + for($i=0;$i<$nooffields;$i++) + $list .= ""; + $list .=''; + } + if($noofdata != '') + { + for($j=0;$j<$noofdata;$j++) + { + if($j==0 || $j%2==0) + $list .=''; + else + $list .=''; + + for($i=0;$i<$nooffields;$i++) + { + $data =$data_arr[$j][$i]['fielddata']; + if($data == '') + $data =' '; + $list .= ""; + } + $list .=''; + } + + $list .= ''; +} +return $list; +} + + + + + + +// The function to get html format url_list data +// input array +// output htmlsource list array +function getblockurl_fieldlistview($block_array,$block) +{ + $header_arr =$block_array[0][$block]['head'][0][0]; + $nooffields=count($header_arr); + $data_arr=$block_array[1][$block]['data']; + $noofdata=count($data_arr); + if($nooffields!='') + { + $list .=''; + for($i=0;$i<$nooffields;$i++) + $list .= ""; + $list .=''; + } + if($noofdata != '') + { + for($j=0;$j<$noofdata;$j++) + { + for($j1=0;$j1'.$data.""; + } + else + $list .= ""; + } + $list .=''; + } + } + } + $list .= ''; + +return $list; +} +/* Function to Show the languages in the Login page +* Takes an array from PortalConfig.php file $language +* Returns a list of available Language +*/ +function getPortalLanguages() { + global $languages,$default_language; + foreach($languages as $name => $label) { + if(strcmp($default_language,$name) == 0){ + $list .= ''; + } else { + $list .= ''; + } + } + return $list; +} +/* Function to set the Current Language + * Sets the Session with the Current Language + */ +function setPortalCurrentLanguage() { + global $default_language; + if(isset($_REQUEST['login_language']) && $_REQUEST['login_language'] != ''){ + $_SESSION['portal_login_language'] = $_REQUEST['login_language']; + } else { + $_SESSION['portal_login_language'] = $default_language; + } +} + +/* Function to get the Current Language + * Returns the Current Language + */ +function getPortalCurrentLanguage() { + global $default_language; + if(isset($_SESSION['portal_login_language']) && $_SESSION['portal_login_language'] != ''){ + $default_language = $_SESSION['portal_login_language']; + } + return $default_language; +} \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/index.php b/oss/vtiger/trunk/customerportal/index.php new file mode 100644 index 00000000..da3fefda --- /dev/null +++ b/oss/vtiger/trunk/customerportal/index.php @@ -0,0 +1,280 @@ + "$email"); + $result = $client->call('send_mail_for_password', $params); + $_REQUEST['mail_send_message'] = $result; + require_once("supportpage.php"); +} +elseif($_REQUEST['logout'] == 'true') +{ + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + $params = Array(Array('id' => "$customerid", 'sessionid'=>"$sessionid", 'flag'=>"logout")); + $result = $client->call('update_login_details', $params); + + session_unregister('customer_id'); + session_unregister('customer_name'); + session_unregister('last_login'); + session_unregister('support_start_date'); + session_unregister('support_end_date'); + session_unregister('__permitted_modules'); + session_unregister('customer_account_id'); + session_destroy(); + include("login.php"); +} +else +{ + $module = ''; + $action = 'login.php'; + $isAjax = ($_REQUEST['ajax'] == 'true'); + + if($_SESSION['customer_id'] != '') + { + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + // Set customer account id + if(isset($_SESSION['customer_account_id'])) { + $account_id = $_SESSION['customer_account_id']; + } else { + $params = Array('id'=>$customerid); + $account_id = $client->call('get_check_account_id', $params, $Server_Path, $Server_Path); + $_SESSION['customer_account_id'] = $account_id; + } + // End + $is_logged = 1; + + //Added to download attachments + if($_REQUEST['downloadfile'] == 'true') + { + $filename = $_REQUEST['filename']; + $fileType = $_REQUEST['filetype']; + //$fileid = $_REQUEST['fileid']; + $filesize = $_REQUEST['filesize']; + + //Added for enhancement from Rosa Weber + + if($_REQUEST['module'] == 'Invoice' || $_REQUEST['module'] == 'Quotes') + { + $id=$_REQUEST['id']; + $block = $_REQUEST['module']; + $params = array('id' => "$id", 'block'=>"$block", 'contactid'=>"$customerid",'sessionid'=>"$sessionid"); + $fileContent = $client->call('get_pdf', $params, $Server_Path, $Server_Path); + $fileType ='application/pdf'; + $fileContent = $fileContent[0]; + $filesize = strlen(base64_decode($fileContent)); + $filename = "$block.pdf"; + + } + else if($_REQUEST['module'] == 'Documents') + { + $id=$_REQUEST['id']; + $folderid = $_REQUEST['folderid']; + $block = $_REQUEST['module']; + $params = array('id' => "$id", 'folderid'=> "$folderid",'block'=>"$block", 'contactid'=>"$customerid",'sessionid'=>"$sessionid"); + $result = $client->call('get_filecontent_detail', $params, $Server_Path, $Server_Path); + $fileType=$result[0]['filetype']; + $filesize=$result[0]['filesize']; + $filename=html_entity_decode($result[0]['filename']); + $fileContent=$result[0]['filecontents']; + } + else + { + $ticketid = $_REQUEST['ticketid']; + $fileid = $_REQUEST['fileid']; + //we have to get the content by passing the customerid, fileid and filename + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + $params = array(Array('id'=>$customerid,'fileid'=>$fileid,'filename'=>$filename,'sessionid'=>$sessionid,'ticketid'=>$ticketid)); + $fileContent = $client->call('get_filecontent', $params, $Server_Path, $Server_Path); + $fileContent = $fileContent[0]; + $filesize = strlen(base64_decode($fileContent)); + + } + // : End + + //we have to get the content by passing the customerid, fileid and filename + $customerid = $_SESSION['customer_id']; + $sessionid = $_SESSION['customer_sessionid']; + + header("Content-type: $fileType"); + header("Content-length: $filesize"); + header("Cache-Control: private"); + header("Content-Disposition: attachment; filename=$filename"); + header("Content-Description: PHP Generated Data"); + echo base64_decode($fileContent); + exit; + } + if($_REQUEST['module'] != '' && $_REQUEST['action'] != '') + { + $customerid = $_SESSION['customer_id']; + + $permission = array(); + // Look if we have the information already + if(isset($_SESSION['__permitted_modules'])) { + $permission = $_SESSION['__permitted_modules']; + } else { + // Get the information from server + $params = array($customerid); + $permission = $client->call('get_modules',$params,$Server_path,$Server_path); + // Store for futher re-use + $_SESSION['__permitted_modules'] = $permission; + } + $isPermitted = false; + for($i=0;$icall('get_modules',$params,$Server_path,$Server_path); + // Store for futher re-use + $_SESSION['__permitted_modules'] = $permission; + } + $module = $permission[0]; + $action = "index.php"; + } + } + $filename = $module.$action; + + if($is_logged == 1) + { + include("HelpDesk/Utils.php"); + global $default_charset, $default_language; + $default_language = getPortalCurrentLanguage(); + include("language/$default_language.lang.php"); + header('Content-Type: text/html; charset='.$default_charset); + + if(!$isAjax) { + include("header.html"); + } + + ?> + + '; + + // Look if we have the information already + $tabArray = array(); + if(isset($_SESSION['__permitted_modules'])) { + $tabArray = $_SESSION['__permitted_modules']; + } else { + // Get the information from server + $params = array(); + $tabArray = $client->call('get_modules',$params,$Server_path,$Server_path); + // Store for futher re-use + $_SESSION['__permitted_modules'] = $tabArray; + } + $module = $_REQUEST['module']; + foreach($tabArray as $key => $tabName) { + if(strcmp(rtrim($module,"/"),$tabName) == 0) { + ?> + document.getElementById("").className = "dvtSelectedCell"; + + document.getElementById("").className = "dvtUnSelectedCell"; + '; + } + ?> + + call('get_modules',$params,$Server_path,$Server_path); + } + $module = $permission[0]; + + checkFileAccess("$module/index.php"); + include("$module/index.php"); + } + if(!$isAjax) { + include("footer.html"); + } + } + else { + header("Location: login.php"); + } + +} + +?> diff --git a/oss/vtiger/trunk/customerportal/js/acdropdown.js b/oss/vtiger/trunk/customerportal/js/acdropdown.js new file mode 100644 index 00000000..f5aff8d0 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/js/acdropdown.js @@ -0,0 +1,1546 @@ +// +// This script was created +// by Mircho Mirev +// mo /mo@momche.net/ +// Copyright (c) 2004-2005 Mircho Mirev +// +// :: feel free to use it BUT +// :: if you want to use this code PLEASE send me a note +// :: and please keep this disclaimer intact +// + +function cAutocomplete( sInputId ) +{ + this.init( sInputId ) +} + +cAutocomplete.CS_NAME = 'Autocomplete component' +cAutocomplete.CS_OBJ_NAME = 'AC_COMPONENT' +cAutocomplete.CS_LIST_PREFIX = 'ACL_' +cAutocomplete.CS_BUTTON_PREFIX = 'ACB_' +cAutocomplete.CS_INPUT_PREFIX = 'AC_' +cAutocomplete.CS_HIDDEN_INPUT_PREFIX = 'ACH_' +cAutocomplete.CS_INPUT_CLASSNAME = 'dropdown' + +cAutocomplete.CB_AUTOINIT = true + +cAutocomplete.CB_AUTOCOMPLETE = false + +cAutocomplete.CB_FORCECORRECT = false + +//the separator when autocompleting multiple values +cAutocomplete.CB_MATCHSUBSTRING = false +cAutocomplete.CS_SEPARATOR = ',' + +//the separator of associative arrays +cAutocomplete.CS_ARRAY_SEPARATOR = ',' + +//match the input string only against the begining of the strings +//or anywhere in the string +cAutocomplete.CB_MATCHSTRINGBEGIN = true + +cAutocomplete.CN_OFFSET_TOP = 2 +cAutocomplete.CN_OFFSET_LEFT = -1 + +cAutocomplete.CN_LINE_HEIGHT = 19 +cAutocomplete.CN_NUMBER_OF_LINES = 10 +cAutocomplete.CN_HEIGHT_FIX = 2 + +cAutocomplete.CN_CLEAR_TIMEOUT = 300 +cAutocomplete.CN_SHOW_TIMEOUT = 300 +cAutocomplete.CN_REMOTE_SHOW_TIMEOUT = 500 +cAutocomplete.CN_MARK_TIMEOUT = 400 + +cAutocomplete.hListDisplayed = null +cAutocomplete.nCount = 0 + +cAutocomplete.autoInit = function() +{ + var nI = 0 + var hACE = null + var sLangAtt + + var nInputsLength = document.getElementsByTagName( 'INPUT' ).length + for( nI = 0; nI < nInputsLength; nI++ ) + { + if( document.getElementsByTagName( 'INPUT' )[ nI ].type.toLowerCase() == 'text' ) + { + sLangAtt = document.getElementsByTagName( 'INPUT' )[ nI ].getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( document.getElementsByTagName( 'INPUT' )[ nI ].id == null || document.getElementsByTagName( 'INPUT' )[ nI ].id.length == 0 ) + { + document.getElementsByTagName( 'INPUT' )[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( document.getElementsByTagName( 'INPUT' )[ nI ].id ) + } + } + } + + var nTALength = document.getElementsByTagName( 'TEXTAREA' ).length + for( nI = 0; nI < nTALength; nI++ ) + { + sLangAtt = document.getElementsByTagName( 'TEXTAREA' )[ nI ].getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( document.getElementsByTagName( 'TEXTAREA' )[ nI ].id == null || document.getElementsByTagName( 'TEXTAREA' )[ nI ].id.length == 0 ) + { + document.getElementsByTagName( 'TEXTAREA' )[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( document.getElementsByTagName( 'TEXTAREA' )[ nI ].id ) + } + } + + + var nSelectsLength = document.getElementsByTagName( 'SELECT' ).length + var aSelect = null + for( nI = 0; nI < nSelectsLength; nI++ ) + { + aSelect = document.getElementsByTagName( 'SELECT' )[ nI ] + sLangAtt = aSelect.getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( aSelect.id == null || aSelect.id.length == 0 ) + { + aSelect.id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( aSelect.id ) + nSelectsLength-- + nI-- + } + } +} + +if( cAutocomplete.CB_AUTOINIT ) +{ + if( window.attachEvent ) + { + window.attachEvent( 'onload', cAutocomplete.autoInit ) + } + else if( window.addEventListener ) + { + window.addEventListener( 'load', cAutocomplete.autoInit, false ) + } +} + +cAutocomplete.prototype.init = function( sInputId ) +{ + this.sInputId = sInputId + this.sListId = cAutocomplete.CS_LIST_PREFIX + sInputId + + this.sObjName = cAutocomplete.CS_OBJ_NAME + '_obj_' + (cAutocomplete.nCount++) + this.hObj = this.sObjName + + this.hActiveSelection = null + this.nSelectedItemIdx = -1 + + //the value of the input before the list is displayed + this.sLastActiveValue = '' + this.sActiveValue = '' + this.bListDisplayed = false + this.nItemsDisplayed = 0 + + //if I transform a select option or the supplied array is associative I create a hidden input + //with the name of the original input and replace the original input's name + this.bAssociative = false + this.sHiddenInputId = null + this.bHasButton = false + + //the actual data + this.aData = null + //the search array object + this.aSearchData = new Array() + this.bSorted = false + + //the length of the last matched typed string + this.nLastMatchLength = 0 + + this.bForceCorrect = cAutocomplete.CB_FORCECORRECT + var sForceCorrect = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_forcecorrect' ) + if( sForceCorrect != null && sForceCorrect.length > 0 ) + { + this.bForceCorrect = eval( sForceCorrect ) + } + + //match a only from the beginning or anywhere in the values + this.bMatchBegin = cAutocomplete.CB_MATCHSTRINGBEGIN + var sMatchBegin = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_matchbegin' ) + if( sMatchBegin != null && sMatchBegin.length > 0 ) + { + this.bMatchBegin = eval( sMatchBegin ) + } + //match substrings separated by cAutocomplete.CS_SEPARATOR + this.bMatchSubstring = cAutocomplete.CB_MATCHSUBSTRING + var sMatchSubstring = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_matchsubstring' ) + if( sMatchSubstring != null && sMatchSubstring.length > 0 ) + { + this.bMatchSubstring = true + } + + //autocomplete with the first option from the list + this.bAutoComplete = cAutocomplete.CB_AUTOCOMPLETE + this.bAutocompleted = false + var sAutoComplete = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_complete' ) + if( sAutoComplete != null && sAutoComplete.length > 0 ) + { + this.bAutoComplete = eval( sAutoComplete ) + } + //format function + this.formatOptions = null + var sFormatFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_format' ) + if( sFormatFunction != null && sFormatFunction.length > 0 ) + { + this.formatOptions = eval( sFormatFunction ) + } + //onselect callback function - get called when a new option is selected + this.onSelect = null + var sOnSelectFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_onselect' ) + if( sOnSelectFunction != null && sOnSelectFunction.length > 0 ) + { + this.onSelect = eval( sOnSelectFunction ) + } + + //I assume that we always have the associative type + //you can turn it off only with the autocomplete_assoc=false attribute + this.bAssociative = true + var sAssociative = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_assoc' ) + if( sAssociative != null && sAssociative.length > 0 ) + { + if( sAssociative == 'false' ) + { + this.bAssociative = false + } + } + + //if we have remote list then we postpone the list creation + if( this.getListArrayType() != 'url' ) + { + this.bRemoteList = false + } + else + { + this.bRemoteList = true + this.sListURL = this.getListURL() + this.hXMLHttp = XmlHttp.create() + } + this.initListArray() + this.initListContainer() + //this.createList() + this.initInput() + + eval( this.hObj + '= this' ) +} + +cAutocomplete.prototype.initInput = function() +{ + var hInput = document.getElementById( this.sInputId ) + hInput.hAutocomplete = this + var hContainer = document.getElementById( this.sListId ) + hContainer.hAutocomplete = this + + //any element (and it's children) with display:none have offset values of 0 (in mozilla) + var hOWInput = hInput.cloneNode( true ) + hOWInput.style.position = 'absolute' + hOWInput.style.top = '-1000px' + document.body.appendChild( hOWInput ) + var nWidth = hOWInput.offsetWidth + document.body.removeChild( hOWInput ) + + var sInputName = hInput.name + var hForm = hInput.form + var bHasButton = false + var sHiddenValue = hInput.value + var sValue = hInput.type.toLowerCase() == 'text' ? hInput.value : '' + + var sHasButton = hInput.getAttribute( 'autocomplete_button' ) + if( sHasButton != null && sHasButton.length > 0 ) + { + bHasButton = true + } + + //if it is a select - I unconditionally add a button + if( hInput.type.toLowerCase() == 'select-one' ) + { + bHasButton = true + if( hInput.selectedIndex >= 0 ) + { + sHiddenValue = hInput.options[ hInput.selectedIndex ].value + sValue = hInput.options[ hInput.selectedIndex ].text + } + } + + //this is the case when the control is a transformed select or the list supplied is of the type - key,value not only values + if( hForm ) + { + var hHiddenInput = document.createElement( 'INPUT' ) + hHiddenInput.id = cAutocomplete.CS_HIDDEN_INPUT_PREFIX + this.sInputId + hHiddenInput.type = 'hidden' + hForm.appendChild( hHiddenInput ) + + if( this.bAssociative ) + { + hHiddenInput.name = sInputName + hInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + else + { + hHiddenInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + + hHiddenInput.value = sHiddenValue + this.sHiddenInputId = hHiddenInput.id + } + + if( bHasButton ) + { + this.bHasButton = true + + var hInputContainer = document.createElement( 'DIV' ) + hInputContainer.className = 'acinputContainer' + hInputContainer.style.width = nWidth + + var hInputButton = document.createElement( 'INPUT' ) + hInputButton.id = cAutocomplete.CS_BUTTON_PREFIX + this.sInputId + hInputButton.type = 'button' + hInputButton.className = 'button' + hInputButton.tabIndex = hInput.tabIndex + 1 + hInputButton.hAutocomplete = this + + var hNewInput = document.createElement( 'INPUT' ) + if( this.bAssociative ) + { + hNewInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + else + { + hNewInput.name = sInputName + } + + hNewInput.type = 'text' + hNewInput.value = sValue + hNewInput.style.width = nWidth-20 + hNewInput.className = cAutocomplete.CS_INPUT_CLASSNAME + hNewInput.tabIndex = hInput.tabIndex + hNewInput.hAutocomplete = this + + hInputContainer.appendChild( hNewInput ) + hInputContainer.appendChild( hInputButton ) + + hInput.parentNode.replaceChild( hInputContainer, hInput ) + + hNewInput.id = this.sInputId + hInput = hNewInput + } + + if( hInput.attachEvent ) + { + hInput.attachEvent( 'onkeyup', cAutocomplete.onInputKeyUp ) + hInput.attachEvent( 'onkeyup', cAutocomplete.saveCaretPosition ) + hInput.attachEvent( 'onkeydown', cAutocomplete.onInputKeyDown ) + hInput.attachEvent( 'onblur', cAutocomplete.onInputBlur ) + hInput.attachEvent( 'onfocus', cAutocomplete.onInputFocus ) + + if( hInputButton ) + { + hInputButton.attachEvent( 'onclick', cAutocomplete.onButtonClick ) + } + } + else if( hInput.addEventListener ) + { + hInput.addEventListener( 'keyup', cAutocomplete.onInputKeyUp, false ) + hInput.addEventListener( 'keyup', cAutocomplete.saveCaretPosition, false ) + hInput.addEventListener( 'keydown', cAutocomplete.onInputKeyDown, false ) + hInput.addEventListener( 'keypress', cAutocomplete.onInputKeyPress, false ) + hInput.addEventListener( 'blur', cAutocomplete.onInputBlur, false ) + hInput.addEventListener( 'focus', cAutocomplete.onInputFocus, false ) + + if( hInputButton ) + { + hInputButton.addEventListener( 'click', cAutocomplete.onButtonClick, false ) + } + } + + //I don't need the standard autocomplete + hInput.setAttribute( 'autocomplete', 'OFF' ) + + if( hForm ) + { + if( hForm.attachEvent ) + { + hForm.attachEvent( 'onsubmit', cAutocomplete.onFormSubmit ) + } + else if( hForm.addEventListener ) + { + hForm.addEventListener( 'submit', cAutocomplete.onFormSubmit, false ) + } + } +} + +cAutocomplete.prototype.initListContainer = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hContainer = document.createElement( 'DIV' ) + hContainer.className = 'autocomplete_holder' + hContainer.id = this.sListId + hContainer.style.zIndex = 10000 + cAutocomplete.nCount + hContainer.hAutocomplete = this + + var hFirstBorder = document.createElement( 'DIV' ) + hFirstBorder.className = 'autocomplete_firstborder' + var hSecondBorder = document.createElement( 'DIV' ) + hSecondBorder.className = 'autocomplete_secondborder' + + var hList = document.createElement( 'UL' ) + hList.className = 'autocomplete' + + hSecondBorder.appendChild( hList ) + hFirstBorder.appendChild( hSecondBorder ) + hContainer.appendChild( hFirstBorder ) + document.body.appendChild( hContainer ) + + if( hContainer.attachEvent ) + { + hContainer.attachEvent( 'onblur', cAutocomplete.onListBlur ) + hContainer.attachEvent( 'onfocus', cAutocomplete.onListFocus ) + } + else if( hInput.addEventListener ) + { + hContainer.addEventListener( 'blur', cAutocomplete.onListBlur, false ) + hContainer.addEventListener( 'focus', cAutocomplete.onListFocus, false ) + } + + + if( hContainer.attachEvent ) + { + hContainer.attachEvent( 'onclick', cAutocomplete.onItemClick ) + } + else if( hContainer.addEventListener ) + { + hContainer.addEventListener( 'click', cAutocomplete.onItemClick, false ) + } +} + +cAutocomplete.prototype.createList = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[0] + if( hList ) + { + hList = hList.parentNode.removeChild( hList ) + while( hList.hasChildNodes() ) + { + hList.removeChild( hList.childNodes[ 0 ] ) + } + } + + var hListItem = null + var hListItemLink = null + var hArrKey = null + var sArrEl = null + + var hArr = this.aData + var nI = 0 + for( hArrKey in hArr ) + { + sArrEl = hArr[ hArrKey ] + hListItem = document.createElement( 'LI' ) + hListItemLink = document.createElement( 'A' ) + hListItemLink.setAttribute( 'itemvalue', hArrKey ) + hListItemLink.href = '#' + hListItemLink.appendChild( document.createTextNode( sArrEl ) ) + hListItemLink.realText = sArrEl + if( nI == this.nSelectedItemIdx ) + { + this.hActiveSelection = hListItemLink + this.hActiveSelection.className = 'selected' + } + hListItem.appendChild( hListItemLink ) + hList.appendChild( hListItem ) + this.aSearchData[ nI++ ] = sArrEl.toLowerCase() + } + var hSecondBorder = hContainer.firstChild.firstChild + hSecondBorder.appendChild( hList ) + this.bListUpdated = false +} + +/* list array functions */ + +cAutocomplete.prototype.initListArray = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hArr = null + + if( hInput.type.toLowerCase() == 'select-one' ) + { + hArr = new Object() + for( var nI = 0; nI < hInput.options.length; nI++ ) + { + hArrKey = hInput.options.item( nI ).value + sArrEl = hInput.options.item( nI ).text + hArr[ hArrKey ] = sArrEl + if( hInput.options.item( nI ).selected ) + { + this.nSelectedItemIdx = nI + } + } + } + else + { + var sAA = hInput.getAttribute( 'autocomplete_list' ) + var sAAS = hInput.getAttribute( 'autocomplete_list_sort' ) + + var sArrayType = this.getListArrayType() + + switch( sArrayType ) + { + case 'array' : hArr = eval( sAA.substring( 6 ) ) + break + + case 'list' : hArr = new Array() + var hTmpArray = sAA.substring( 5 ).split( '|' ) + var aValueArr + for( hKey in hTmpArray ) + { + aValueArr = hTmpArray[ hKey ].split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( aValueArr.length == 1 ) + { + hArr[ hKey ] = hTmpArray[ hKey ] + this.bAssociative = false + } + else + { + hArr[ aValueArr[ 0 ] ] = aValueArr[ 1 ] + } + } + break + } + if( sAAS != null && eval( sAAS ) ) + { + this.bSorted = true + this.aData = hArr.sort() + hArr = hArr.sort() + } + } + this.setArray( hArr ) +} + +cAutocomplete.prototype.setArray = function( sArray ) +{ + if( typeof sArray == 'string' ) + { + this.aData = eval( sArray ) + } + else + { + this.aData = sArray + } + this.bListUpdated = true +} + +//use this function to change the list of autocomplete values to a new one +//supply as an argument the name as a literal of an JS array object +//well things changed - you can supply an actual array too +cAutocomplete.prototype.setListArray = function( sArray ) +{ + this.setArray( sArray ) + this.updateAndShowList() +} + +cAutocomplete.prototype.getListArrayType = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sAA = hInput.getAttribute( 'autocomplete_list' ) + if( sAA != null && sAA.length > 0 ) + { + if( sAA.indexOf( 'array:' ) >= 0 ) + { + return 'array' + } + else if( sAA.indexOf( 'list:' ) >= 0 ) + { + return 'list' + } + else if( sAA.indexOf( 'url:' ) >= 0 ) + { + return 'url' + } + } +} + +cAutocomplete.prototype.getListURL = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sAA = hInput.getAttribute( 'autocomplete_list' ) + if( sAA != null && sAA.length > 0 ) + { + if( sAA.indexOf( 'url:' ) >= 0 ) + { + return sAA.substring( 4 ) + } + } +} + +cAutocomplete.prototype.setListURL = function( sURL ) +{ + this.sListURL = sURL; +} + +cAutocomplete.onXmlHttpLoad = function( hThis ) +{ + if( hThis.hXMLHttp.readyState == 4 ) + { + var hError = hThis.hXMLHttp.parseError + if( hError && hError.errorCode != 0 ) + { + alert( hError.reason ) + } + else + { + hThis.afterRemoteLoad() + } + } +} + +cAutocomplete.prototype.loadListArray = function() +{ + var sURL = this.sListURL + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + sStartWith = sStartWith.replace( /^\s/, '' ) + sStartWith = sStartWith.replace( /\s$/, '' ) + if( sURL.indexOf( '[S]' ) >= 0 ) + { + sURL = sURL.replace( '[S]', sStartWith ) + } + else + { + sURL += this.sActiveValue + } + this.hXMLHttp.open( 'GET', sURL, true ) + this.hXMLHttp.onreadystatechange = new Function( 'var sAC = "'+this.sObjName+'"; cAutocomplete.onXmlHttpLoad( eval( sAC ) )' ) + this.hXMLHttp.send( null ) +} + +cAutocomplete.prototype.afterRemoteLoad = function() +{ + var hInput = document.getElementById( this.sInputId ) + + var hArr = new Array() + var hTmpArray = this.hXMLHttp.responseText.split( '|' ) + var aValueArr + for( hKey in hTmpArray ) + { + aValueArr = hTmpArray[ hKey ].split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( aValueArr.length == 1 ) + { + hArr[ hKey ] = hTmpArray[ hKey ] + } + else + { + hArr[ aValueArr[ 0 ] ] = aValueArr[ 1 ] + } + } + + hInput.className = '' + hInput.readonly = false + hInput.value = this.sActiveValue + this.setListArray( hArr ) +} + +/**/ + +cAutocomplete.prototype.prepareList = function( bFullList ) +{ + var hInput = document.getElementById( this.sInputId ) + this.sActiveValue = hInput.value + + //check if this was invoked by a key that did not change the value + var sST = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + var sLST = this.getStringForAutocompletion( this.sLastActiveValue, this.nInsertPoint ) + + if( sLST != sST || bFullList || !this.bListDisplayed || this.bMatchSubstring ) + { + if( this.bRemoteList ) + { + hInput.className = 'search' + hInput.readonly = true + hInput.value = 'plase wait...' + this.loadListArray() + return + } + this.updateAndShowList( bFullList ) + } +} + +cAutocomplete.prototype.updateAndShowList = function( bFullList ) +{ + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var hInput = document.getElementById( this.sInputId ) + + if( this.bListUpdated ) + { + this.createList() + } + + //stupid hack just for speed + var sST = this.bMatchSubstring ? this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) : this.sActiveValue + var sLST = this.bMatchSubstring ? this.getStringForAutocompletion( this.sLastActiveValue, this.nInsertPoint ) : this.sLastActiveValue + + //nothing changed since last type - maybe only function keys were pressed + //this is the case when for example the down key was pressed + if( sST == sLST ) + { + if( !this.bMatchSubstring ) + { + bFullList = true + } + } + this.filterOptions( bFullList ) + + if( this.nItemsDisplayed == 0 ) + { + if( this.bForceCorrect ) + { + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, '' ) + cAutocomplete.markInputRange( hInput, this.nLastMatchLength, aPos[0] ) + } + } + + this.sLastActiveValue = this.sActiveValue + + if( this.nItemsDisplayed > 0 ) + { + if( !bFullList || this.bMatchSubstring ) + { + this.deselectOption() + } + if( this.bAutoComplete && this.nItemsDisplayed == 1 ) + { + //test if we have a full match i.e. the user typed the entire value + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + var sItemText = hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ].realText + if( sStartWith.toLowerCase() == sItemText.toLowerCase() ) + { + this.selectOption( hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ] ) + this.hideOptions() + //and do not show the list + return + } + } + if( this.bAutoComplete && !bFullList ) + { + this.selectOption( hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ] ) + } + this.showList() + } + else + { + this.clearList() + } +} + +cAutocomplete.prototype.showList = function() +{ + if( cAutocomplete.hListDisplayed ) + { + cAutocomplete.hListDisplayed.clearList() + } + var hInput = document.getElementById( this.sInputId ) + var nTop = cDomObject.getOffsetParam( hInput, 'offsetTop' ) + var nLeft = cDomObject.getOffsetParam( hInput, 'offsetLeft' ) + var hContainer = document.getElementById( this.sListId ) + + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + if( this.bHasButton ) + { + hContainer.style.width = document.getElementById( this.sInputId ).parentNode.offsetWidth + } + else + { + hContainer.style.width = document.getElementById( this.sInputId ).offsetWidth + } + var nNumLines = ( this.nItemsDisplayed < cAutocomplete.CN_NUMBER_OF_LINES ) ? this.nItemsDisplayed : cAutocomplete.CN_NUMBER_OF_LINES; + hList.style.height = nNumLines * cAutocomplete.CN_LINE_HEIGHT + cAutocomplete.CN_HEIGHT_FIX + 'px' + + hContainer.style.top = nTop + hInput.offsetHeight + cAutocomplete.CN_OFFSET_TOP + 'px' + hContainer.style.left = nLeft + cAutocomplete.CN_OFFSET_LEFT + 'px' + + hContainer.style.display = 'none' + hContainer.style.visibility = 'visible' + hContainer.style.display = 'block' + + cAutocomplete.hListDisplayed = this + this.bListDisplayed = true +} + +cAutocomplete.prototype.binarySearch = function( sFilter ) +{ + var nLow = 0 + var nHigh = this.aSearchData.length - 1 + var nMid + var nTry, nLastTry + var sData + var nLen = sFilter.length + + var lastTry + + while ( nLow <= nHigh ) + { + nMid = ( nLow + nHigh ) / 2 + nTry = ( nMid < 1 ) ? 0 : parseInt( nMid ) + + sData = this.aSearchData[ nTry ].substr( 0, nLen ) + + if ( sData < sFilter ) + { + nLow = nTry + 1 + continue + } + if ( sData > sFilter ) + { + nHigh = nTry - 1 + continue + } + if ( sData == sFilter ) + { + nHigh = nTry - 1 + nLastTry = nTry + continue + } + return nTry + } + + if ( typeof ( nLastTry ) != "undefined" ) + { + return nLastTry + } + else + { + return null + } +} + +cAutocomplete.prototype.getStringForAutocompletion = function( sString, nPos ) +{ + if( sString == null || sString.length == 0 ) + { + return '' + } + if( this.bMatchSubstring ) + { + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S*)(\s*)(\,?)$/g, '$3' ) + return sStr + } + else + { + return sString + } +} + +cAutocomplete.prototype.insertString = function( sString, nPos, sInsert ) +{ + if( this.bMatchSubstring ) + { + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S?[\S\s]*\S?)(\s*)(\,?)$/g, '$1$2'+sInsert+'$4$5' ) + sStr = sString.substr( 0, nStartPos ) + sStr + sString.substr( nEndPos ) + return sStr + } + else + { + return sInsert + } +} + +cAutocomplete.prototype.getInsertPos = function( sString, nPos, sInsert ) +{ + nPos = nPos == null ? 0 : nPos + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S?[\S\s]*\S?)(\s*)(\,?)$/g, '$1$2'+sInsert ) + return [ nPos, nStartPos + sStr.length ] +} + +cAutocomplete.prototype.filterOptions = function( bShowAll ) +{ + if( this.hActiveSelection && !bShowAll ) + { + this.hActiveSelection.className = '' + } + if( typeof bShowAll == 'undefined' ) + { + bShowAll = false + } + + var hInput = document.getElementById( this.sInputId ) + + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + if( bShowAll ) + { + sStartWith = '' + } + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + var hLinkItem = null + var nCount = 0 + + var hParent = hList.parentNode + var hList = hList.parentNode.removeChild( hList ) + var hTItems = hList.childNodes + + this.nItemsDisplayed = 0 + + if( sStartWith.length == 0 ) + { + for( var nI = 0; nI < nItemsLength; nI++ ) + { + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + } + + nCount = nItemsLength + + if( nItemsLength > 0 ) + { + this.nFirstDisplayed = 0 + this.nLastDisplayed = nItemsLength - 1 + } + else + { + this.nFirstDisplayed = this.nLastDisplayed = -1 + } + + //this.nLastMatchLength = 0 + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, sStartWith ) + this.nLastMatchLength = aPos[0] + } + else + { + this.nFirstDisplayed = this.nLastDisplayed = -1 + sStartWith = sStartWith.toLowerCase() + var bEnd = false + if( this.bSorted && this.bMatchBegin ) + { + var nStartAt = this.binarySearch( sStartWith ) + for( var nI = 0; nI < nItemsLength; nI++ ) + { + hTItems[ nI ].style.display = 'none' + if( nI >= nStartAt && !bEnd ) + { + if( !bEnd && this.aSearchData[ nI ].indexOf( sStartWith ) != 0 ) + { + bEnd = true + continue + } + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + nCount++ + if( this.nFirstDisplayed < 0 ) + { + this.nFirstDisplayed = nI + } + this.nLastDisplayed = nI + } + } + } + else + { + for( var nI = 0; nI < nItemsLength; nI++ ) + { + hTItems[ nI ].style.display = 'none' + if( ( this.bMatchBegin && this.aSearchData[ nI ].indexOf( sStartWith ) == 0 ) || ( !this.bMatchBegin && this.aSearchData[ nI ].indexOf( sStartWith ) >= 0 ) ) + { + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + nCount++ + if( this.nFirstDisplayed < 0 ) + { + this.nFirstDisplayed = nI + } + this.nLastDisplayed = nI + } + } + } + + if( nCount > 0 ) + { + //this.nLastMatchLength = this.sActiveValue.length + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, sStartWith ) + this.nLastMatchLength = aPos[0] + } + } + hParent.appendChild( hList ) + this.nItemsDisplayed = nCount +} + +cAutocomplete.prototype.hideOptions = function() +{ + var hContainer = document.getElementById( this.sListId ) + hContainer.style.visibility = 'hidden' + cAutocomplete.hListDisplayed = null +} + +cAutocomplete.prototype.markAutocompletedValue = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sValue = this.hActiveSelection.realText + if( this.bMatchSubstring ) + { + var aPos = this.getInsertPos( this.sLastActiveValue, this.nInsertPoint, sValue ) + var nStartPos = aPos[ 0 ] + var nEndPos = aPos[ 1 ] + } + else + { + var nStartPos = this.nInsertPoint + var nEndPos = sValue.length + } + this.nStartAC = nStartPos + this.nEndAC = nEndPos + + if( this.hMarkRangeTimeout != null ) + { + clearTimeout( this.hMarkRangeTimeout ) + } + this.hMarkRangeTimeout = setTimeout( 'cAutocomplete.markInputRange2("'+hInput.id+'")', cAutocomplete.CN_MARK_TIMEOUT ) + //cAutocomplete.markInputRange( hInput, nStartPos, nEndPos ) +} + +cAutocomplete.prototype.selectOptionByIndex = function( nOptionIndex ) +{ + if( this.bListUpdated ) + { + this.createList() + } + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + if( nOptionIndex >=0 && nOptionIndex < nItemsLength ) + { + this.selectOption( hList.childNodes[ nOptionIndex ].getElementsByTagName( 'A' )[ 0 ] ) + } +} + +cAutocomplete.prototype.selectOption = function( hNewOption ) +{ + if( this.hActiveSelection ) + { + if( this.hActiveSelection == hNewOption ) + { + return + } + else + { + this.hActiveSelection.className = '' + } + } + this.hActiveSelection = hNewOption + var hInput = document.getElementById( this.sInputId ) + if( this.hActiveSelection != null ) + { + if( this.sHiddenInputId != null ) + { + if( this.bMatchSubstring ) + { + document.getElementById( this.sHiddenInputId ).value = this.hActiveSelection.getAttribute( 'itemvalue' ) + } + else + { + document.getElementById( this.sHiddenInputId ).value = this.hActiveSelection.getAttribute( 'itemvalue' ) + } + } + + this.hActiveSelection.className = 'selected' + if( this.bAutoComplete ) + { + hInput.value = this.insertString( this.sLastActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + this.bAutocompleted = true + this.markAutocompletedValue() + } + else + { + hInput.value = this.insertString( this.sActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + cAutocomplete.setInputCaretPosition( hInput, this.nInsertPoint ) + } + + this.sActiveValue = hInput.value + + if( this.onSelect ) + { + this.onSelect() + } + } + else + { + hInput.value = this.sActiveValue + cAutocomplete.setInputCaretPosition( hInput, this.nInsertPoint ) + } +} + +cAutocomplete.prototype.deselectOption = function( ) +{ + if( this.hActiveSelection != null ) + { + this.hActiveSelection.className = '' + this.hActiveSelection = null + } +} + +cAutocomplete.prototype.clearList = function() +{ + //this.deselectOption() + this.hideOptions() + this.bListDisplayed = false +} + +cAutocomplete.prototype.getPrevDisplayedItem = function( hItem ) +{ + if( hItem == null ) + { + var hContainer = document.getElementById( this.sListId ) + hItem = hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.item( hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.length - 1 ) + } + else + { + hItem = getPrevNodeSibling( hItem.parentNode ) + } + while( hItem != null ) + { + if( hItem.style.display == 'block' ) + { + return hItem + } + hItem = hItem.previousSibling + } + return null +} + +cAutocomplete.prototype.getNextDisplayedItem = function( hItem ) +{ + if( hItem == null ) + { + var hContainer = document.getElementById( this.sListId ) + hItem = hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.item( 0 ) + } + else + { + hItem = getNextNodeSibling( hItem.parentNode ) + } + while( hItem != null ) + { + if( hItem.style.display == 'block' ) + { + return hItem + } + hItem = hItem.nextSibling + } + return null +} + +cAutocomplete.onInputKeyDown = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hContainer = document.getElementById( hAC.sListId ) + var hInput = document.getElementById( hAC.sInputId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var hEl = getParentByTagName( hElement, 'A' ) + if( hContainer != null && hAC.bListDisplayed ) + { + var hLI = null + var hLINext = null + //the new active selection + if( ( hEvent.keyCode == 13 ) || ( hEvent.keyCode == 27 ) ) + { + var bItemSelected = hEvent.keyCode == 13 ? true : false + hAC.clearList() + } + if( hEvent.keyCode == 38 ) + { + //up key pressed + hLINext = hAC.getPrevDisplayedItem( hAC.hActiveSelection ) + if( hLINext != null ) + { + hAC.selectOption( hLINext.childNodes.item(0) ) + if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES ) + { + if( hList.scrollTop < 5 && hLINext.offsetTop > hList.offsetHeight ) + { + hList.scrollTop = hList.scrollHeight - hList.offsetHeight + } + if( hLINext.offsetTop - hList.scrollTop < 0 ) + { + hList.scrollTop -= hLINext.offsetHeight + } + } + } + else + { + hAC.selectOption( null ) + } + } + else if ( hEvent.keyCode == 40 ) + { + //down key pressed + hLINext = hAC.getNextDisplayedItem( hAC.hActiveSelection ) + if( hLINext != null ) + { + hAC.selectOption( hLINext.childNodes.item(0) ) + if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES ) + { + if( hList.scrollTop > 0 && hList.scrollTop > hLINext.offsetTop ) + { + hList.scrollTop = 0 + } + if( Math.abs( hLINext.offsetTop - hList.scrollTop - hList.offsetHeight ) < 5 ) + { + hList.scrollTop += hLINext.offsetHeight + } + } + } + else + { + hAC.selectOption( null ) + } + } + } + if( hInput.form ) + { + hInput.form.bLocked = true + } + if ( hEvent.keyCode == 13 || hEvent.keyCode == 27 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } +} + +cAutocomplete.onInputKeyPress = function ( hEvent ) +{ + if ( hEvent.keyCode == 13 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } +} + +cAutocomplete.onInputKeyUp = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + //if we press the keys for up down enter or escape skip showing the list + switch( hEvent.keyCode ) + { + case 8 : if( hAC.bAutoComplete && hAC.bAutocompleted ) + { + hAC.bAutocompleted = false + return false + } + break + case 38 : + case 40 : if( hAC.bListDisplayed ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } + break + case 32 : + case 46 : + case 37 : + case 39 : + case 35 : + case 36 : break; + default : if( hEvent.keyCode < 48 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } + break + } + + if( this.hMarkRangeTimeout != null ) + { + clearTimeout( this.hMarkRangeTimeout ) + } + + if( hAC.hShowTimeout ) + { + clearTimeout( hAC.hShowTimeout ) + hAC.hShowTimeout = null + } + var nTimeout = this.bRemoteList ? cAutocomplete.CN_REMOTE_SHOW_TIMEOUT : cAutocomplete.CN_SHOW_TIMEOUT + hAC.hShowTimeout = setTimeout( hAC.hObj+'.prepareList()', nTimeout ) +} + +cAutocomplete.onInputBlur = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + if( hElement.form ) + { + hElement.form.bLocked = false + } + var hAC = hElement.hAutocomplete + if( !hAC.hClearTimeout ) + { + hAC.hClearTimeout = setTimeout( hAC.hObj+'.clearList()', cAutocomplete.CN_CLEAR_TIMEOUT ) + } +} + +cAutocomplete.onInputFocus = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + if( hAC.hClearTimeout ) + { + clearTimeout( hAC.hClearTimeout ) + hAC.hClearTimeout = null + } +} + +cAutocomplete.saveCaretPosition = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + + //there is something weird about hitting up and down keys in a textarea + if( hEvent.keyCode != 38 && hEvent.keyCode != 40 ) + { + hAC.nInsertPoint = cAutocomplete.getInputCaretPosition( hInput ) + } +} + +cAutocomplete.getInputCaretPosition = function( hInput ) +{ + if( typeof hInput.selectionStart != 'undefined' ) + { + if( hInput.selectionStart == hInput.selectionEnd ) + { + return hInput.selectionStart + } + else + { + return hInput.selectionStart + } + } + else if( hInput.createTextRange ) + { + var hSelRange = document.selection.createRange() + if( hInput.tagName.toLowerCase() == 'textarea' ) + { + var hSelBefore = hSelRange.duplicate() + var hSelAfter = hSelRange.duplicate() + hSelRange.moveToElementText( hInput ) + hSelBefore.setEndPoint( 'StartToStart', hSelRange ) + return hSelBefore.text.length + } + else + { + hSelRange.moveStart( 'character', -1*hInput.value.length ) + var nLen = hSelRange.text.length + return nLen + } + } + return null +} + +cAutocomplete.setInputCaretPosition = function( hInput, nPosition ) +{ + if ( hInput.setSelectionRange ) + { + hInput.setSelectionRange( nPosition ,nPosition ) + } + else if ( hInput.createTextRange ) + { + var hRange = hInput.createTextRange() + hRange.moveStart( 'character', nPosition ) + hRange.moveEnd( 'character', nPosition ) + hRange.collapse(true) + hRange.select() + } +} + +cAutocomplete.markInputRange = function( hInput, nStartPos, nEndPos ) +{ + if( hInput.setSelectionRange ) + { + hInput.focus() + hInput.setSelectionRange( nStartPos, nEndPos ) + } + else if( hInput.createTextRange ) + { + var hRange = hInput.createTextRange() + hRange.collapse(true) + hRange.moveStart( 'character', nStartPos ) + hRange.moveEnd( 'character', nEndPos - nStartPos ) + hRange.select() + } +} + +cAutocomplete.markInputRange2 = function( sInputId ) +{ + var hInput = document.getElementById( sInputId ) + var nStartPos = hInput.hAutocomplete.nStartAC + var nEndPos = hInput.hAutocomplete.nEndAC + cAutocomplete.markInputRange( hInput, nStartPos, nEndPos ) +} + + +cAutocomplete.onListBlur = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + hElement = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hAC = hElement.hAutocomplete + if( !hAC.hClearTimeout ) + { + hAC.hClearTimeout = setTimeout( hAC.hObj+'.clearList()', cAutocomplete.CN_CLEAR_TIMEOUT ) + } +} + +cAutocomplete.onListFocus = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + hElement = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hAC = hElement.hAutocomplete + if( hAC.hClearTimeout ) + { + clearTimeout( hAC.hClearTimeout ) + hAC.hClearTimeout = null + } +} + +cAutocomplete.onItemClick = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hContainer = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hEl = getParentByTagName( hElement, 'A' ) + if( hContainer != null ) + { + var hAC = hContainer.hAutocomplete + hAC.selectOption( hEl ) + document.getElementById( hAC.sInputId ).focus() + hAC.clearList() + } + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false +} + +cAutocomplete.onButtonClick = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + if( hInput.disabled ) + { + return + } + hAC.prepareList( true ) + var hInput = document.getElementById( hAC.sInputId ) + hInput.focus() +} + +cAutocomplete.onFormSubmit = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + if( hElement.bLocked ) + { + hElement.bLocked = false + hEvent.returnValue = false + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + return false + } +} diff --git a/oss/vtiger/trunk/customerportal/js/cookies.js b/oss/vtiger/trunk/customerportal/js/cookies.js new file mode 100644 index 00000000..e003e88b --- /dev/null +++ b/oss/vtiger/trunk/customerportal/js/cookies.js @@ -0,0 +1,33 @@ +// Setting cookies +function set_cookie ( name, value, exp_y, exp_m, exp_d, path, domain, secure ) +{ + var cookie_string = name + "=" + escape ( value ); + + if (exp_y) //delete_cookie(name) + { + var expires = new Date ( exp_y, exp_m, exp_d ); + cookie_string += "; expires=" + expires.toGMTString(); + } + + if (path) cookie_string += "; path=" + escape ( path ); + if (domain) cookie_string += "; domain=" + escape ( domain ); + if (secure) cookie_string += "; secure"; + + document.cookie = cookie_string; +} + +// Retrieving cookies +function get_cookie(cookie_name) +{ + var results = document.cookie.match(cookie_name + '=(.*?)(;|$)'); + if (results) return (unescape(results[1])); + else return null; +} + +// Delete cookies +function delete_cookie( cookie_name ) +{ + var cookie_date = new Date ( ); // current date & time + cookie_date.setTime ( cookie_date.getTime() - 1 ); + document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString(); +} \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/js/general.js b/oss/vtiger/trunk/customerportal/js/general.js new file mode 100644 index 00000000..12b91cf3 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/js/general.js @@ -0,0 +1,115 @@ +// JavaScript Document + +function fnLoadValues(obj){ + window.location.href = "index.php?module="+obj+"&action=index"; +} + +function fnDown(obj){ + var tagName = document.getElementById(obj); + if(tagName.style.display == 'block') + tagName.style.display = 'none'; + else + tagName.style.display = 'block'; +} + +function fnShowDiv(obj){ + var tagName = document.getElementById(obj); + tagName.style.visibility = 'visible'; +} + + +function fnHideDiv(obj){ + var tagName = document.getElementById(obj); + tagName.style.visibility = 'hidden'; +} + +function findPosX(obj) { + var curleft = 0; + if (document.getElementById || document.all) { + while (obj.offsetParent) { + curleft += obj.offsetLeft + obj = obj.offsetParent; + } + } + else if (document.layers) {curleft += obj.x;} + return curleft; +} + +function findPosY(obj) { + var curtop = 0; + if (document.getElementById || document.all) { + while (obj.offsetParent) { + curtop += obj.offsetTop + obj = obj.offsetParent; + } + } + else if (document.layers) {curtop += obj.y;} + return curtop; +} + +function fnShow(obj){ + var tagName = document.getElementById('faqDetail'); + var leftSide = findPosX(obj); + var topSide = findPosY(obj); + topSide = topSide - 90; + leftSide = leftSide - 200; + tagName.style.top = topSide + 'px'; + tagName.style.left = leftSide + 'px'; + tagName.style.visibility = 'visible'; +} + +function trim(s) +{ + while (s.substring(0,1) == " ") + { + s = s.substring(1, s.length); + } + while (s.substring(s.length-1, s.length) == ' ') + { + s = s.substring(0,s.length-1); + } + + return s; +} + +function getList(obj, module) +{ + var list_type = obj.value; + var onlymine = true; + if (list_type == 'all') { + onlymine = false; + } + + var appendurl = ''; + var showstatus_ele = document.getElementById('ticket_status_combo'); + if (showstatus_ele != null) { + var showstatus = showstatus_ele.value; + appendurl = '&showstatus='+showstatus; + } + + window.location.href = "index.php?module="+module+"&action=index&onlymine="+onlymine+appendurl; +} + + +function updateCount(fileid){ + +var xmlHttp; +try{ +// Firefox, Opera 8.0+, Safari + xmlHttp=new XMLHttpRequest(); + }catch (e){ + // Internet Explorer + try{ + xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); + }catch (e){ + try{ + xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); + }catch (e){ + alert("Your browser does not support AJAX!"); + return false; + } + } + } + xmlHttp.open("POST","index.php?action=updateCount&module=Documents&file_id="+fileid,true); + xmlHttp.send(null); +} diff --git a/oss/vtiger/trunk/customerportal/js/getobject2.js b/oss/vtiger/trunk/customerportal/js/getobject2.js new file mode 100644 index 00000000..d8125c53 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/js/getobject2.js @@ -0,0 +1,126 @@ +//misc objects +//a simple encapsulation object +//used to query widths and heights + +function cDomObject( sId ) +{ + if( bw.dom || bw.ie ) + { + this.hElement = document.getElementById( sId ) + this.hStyle = this.hElement.style + } +} + +cDomObject.prototype.getWidth = function( ) +{ + return cDomObject.getWidth( this.hElement ) +} + +cDomObject.getWidth = function( hElement ) +{ + if( hElement.currentStyle ) + { + var nWidth = parseInt( hElement.currentStyle.width ) + if( isNaN( nWidth ) ) + { + return parseInt( hElement.offsetWidth ) + } + else + { + return nWidth + } + } + else + { + return parseInt( hElement.offsetWidth ) + } +} + +cDomObject.prototype.getHeight = function( ) +{ + return cDomObject.getHeight( this.hElement ) +} + +cDomObject.getHeight = function( hElement ) +{ + if( hElement.currentStyle ) + { + var nHeight = parseInt( hElement.currentStyle.height ) + if( isNaN( nHeight ) ) + { + return parseInt( hElement.offsetHeight ) + } + else + { + return nHeight + } + } + else + { + return parseInt( hElement.offsetHeight ) + } +} + +cDomObject.prototype.getLeft = function() +{ + return cDomObject.getLeft( this.hElement ) +} + +cDomObject.getLeft = function( hElement ) +{ + return parseInt( hElement.offsetLeft ) +} + +cDomObject.prototype.getTop = function( ) +{ + return cDomObject.getTop( this.hElement ) +} + +cDomObject.getTop = function( hElement ) +{ + return parseInt( hElement.offsetTop ) +} + + +// used to get the absolute position of an relativeli position element +// by accumulating the offset parameters +// example +// cDomObject.getOffsetParam( hElement,'offsetLeft' ) + +cDomObject.getOffsetParam = function( hElement, sParam, hLimitParent ) +{ + var nRes = 0 + if( hLimitParent == null ) + { + hLimitParent = document.body.parentElement + } + while( hElement != hLimitParent ) + { + nRes += eval( 'hElement.' + sParam ) + if( !hElement.offsetParent ) { break } + hElement = hElement.offsetParent + } + return nRes +} + + +// used to get the absolute position of an relativeli position element +// by accumulating the scroll offset parameters +// example +// cDomObject.getScrollOffset( hElement,'Left' ) + +cDomObject.getScrollOffset = function( hElement, sParam, hLimitParent ) +{ + nRes = 0 + if( hLimitParent == null ) + { + hLimitParent = document.body.parentElement + } + while( hElement != hLimitParent ) + { + nRes += eval( 'hElement.scroll' + sParam ) + if( !hElement.offsetParent ) { break } + hElement = hElement.parentNode + } + return nRes +} \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/js/modomt.js b/oss/vtiger/trunk/customerportal/js/modomt.js new file mode 100644 index 00000000..34dcda43 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/js/modomt.js @@ -0,0 +1,259 @@ +// +// This script was created +// by Mircho Mirev +// mo /mo@momche.net/ +// +// :: feel free to use it BUT +// :: if you want to use this code PLEASE send me a note +// :: and please keep this disclaimer intact +// + +if ( document.ELEMENT_NODE == null ) +{ + document.ELEMENT_NODE = 1 + document.TEXT_NODE = 3 +} + + +function getSubNodeByName( hNode, sNodeName ) +{ + if( hNode != null ) + { + var nNc = 0 + var nC = 0 + var hNodeChildren = hNode.childNodes + var hCNode = null + while( nC < hNodeChildren.length ) + { + hCNode = hNodeChildren.item( nC++ ) + if( ( hCNode.nodeType == 1 ) && ( hCNode.nodeName.toLowerCase() == sNodeName ) ) + { + return hCNode + } + } + } + return null +} + +function getPrevNodeSibling( hNode ) +{ + if( hNode != null ) + { + do { + hNode = hNode.previousSibling + } while( hNode != null && hNode.nodeType != 1 ) + return hNode + } +} + +function getNextNodeSibling( hNode ) +{ + if( hNode != null ) + { + do { + hNode = hNode.nextSibling + } while( hNode != null && hNode.nodeType != 1 ) + return hNode + } +} + +function getLastSubNodeByName( hNode, sNodeName ) +{ + if( hNode != null ) + { + var nNc = 0 + var nC = 0 + var hNodeChildren = hNode.childNodes + var hCNode = null + var nLength = hNodeChildren.length - 1 + while( nLength >=0 ) + { + hCNode = hNodeChildren.item( nLength ) + if( ( hCNode.nodeType == 1 ) && ( hCNode.nodeName.toLowerCase() == sNodeName ) ) + { + return hCNode + } + nLength-- + } + } + return null +} + +function getSubNodeByProperty( hNode, sProperty, sPropValue ) +{ + if( hNode != null ) + { + var nNc = 0 + var nC = 0 + var hNodeChildren = hNode.childNodes + var hCNode = null + var sAttribute + var hProp + sPropValue = sPropValue.toLowerCase() + while( nC < hNodeChildren.length ) + { + hCNode = hNodeChildren.item( nC++ ) + if( hCNode.nodeType == document.ELEMENT_NODE ) + { + hProp = eval( 'hCNode.'+sProperty ) + if( typeof( sPropValue ) != 'undefined' ) + { + if( hProp.toLowerCase() == sPropValue ) + { + return hCNode + } + } + else + { + return hCNode + } + } + nNc++ + } + } + return null +} + +function findAttribute( hNode, sAtt ) +{ + sAtt = sAtt.toLowerCase() + for( var nI = 0; nI < hNode.attributes.length; nI++ ) + { + if( hNode.attributes.item( nI ).nodeName.toLowerCase() == sAtt ) + { + return hNode.attributes.item( nI ).nodeValue + } + } + return null +} + +function getSubNodeByAttribute( hNode, sAtt, sAttValue ) +{ + if( hNode != null ) + { + var nNc = 0 + var nC = 0 + var hNodeChildren = hNode.childNodes + var hCNode = null + var sAttribute + sAttValue = sAttValue.toLowerCase() + while( nC < hNodeChildren.length ) + { + hCNode = hNodeChildren.item( nC++ ) + if( hCNode.nodeType == document.ELEMENT_NODE ) + { + sAttribute = hCNode.getAttribute( sAtt ) + if( sAttribute && sAttribute.toLowerCase() == sAttValue ) + return hCNode + } + nNc++ + } + } + return null +} + +function getLastSubNodeByAttribute( hNode, sAtt, sAttValue ) +{ + if( hNode != null ) + { + var nNc = 0 + var nC = 0 + var hNodeChildren = hNode.childNodes + var hCNode = null + var nLength = hNodeChildren.length - 1 + while( nLength >= 0 ) + { + hCNode = hNodeChildren.item( nLength ) + if( hCNode.nodeType == document.ELEMENT_NODE ) + { + sAttribute = hCNode.getAttribute( sAtt ) + if( sAttribute && sAttribute.toLowerCase() == sAttValue ) + return hCNode + } + nLength-- + } + } + return null +} + +function getParentByTagName( hNode, sParentTagName ) +{ + while( ( hNode.tagName ) && !( /(body|html)/i.test( hNode.tagName ) ) ) + { + if( hNode.tagName == sParentTagName ) + { + return hNode + } + hNode = hNode.parentNode + } + return null +} + +function getParentByAttribute( hNode, sAtt, sAttValue ) +{ + while( ( hNode.tagName ) && !( /(body|html)/i.test( hNode.tagName ) ) ) + { + //opera strangely returns non null result sometimes + var sAttr = hNode.getAttribute( sAtt ) + if( sAttr != null && sAttr.toString().length > 0 ) + { + if( sAttValue !== null ) + { + if( sAttr == sAttValue ) + { + return hNode + } + } + else + { + return hNode + } + } + hNode = hNode.parentNode + } + return null +} + +function getParentByProperty( hNode, sProperty, sPropValue ) +{ + while( ( hNode.tagName ) && !( /(body|html)/i.test( hNode.tagName ) ) ) + { + //opera strangely returns non null result sometimes + var hProp = eval( 'hNode.'+sProperty ) + if( hProp != null && hProp.toString().length > 0 ) + { + if( sPropValue !== null ) + { + if( hProp == sPropValue ) + { + return hNode + } + } + else + { + return hNode + } + } + hNode = hNode.parentNode + } + return null +} + + +function getNodeText( hNode ) +{ + if( hNode == null ) + { + return '' + } + var sRes + if( hNode.hasChildNodes() ) + { + sRes = hNode.childNodes.item(0).nodeValue + } + else + { + sRes = hNode.text + } + return sRes +} \ No newline at end of file diff --git a/oss/vtiger/trunk/customerportal/js/prototype.js b/oss/vtiger/trunk/customerportal/js/prototype.js new file mode 100644 index 00000000..d36df2d1 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/js/prototype.js @@ -0,0 +1,2011 @@ +/* Prototype JavaScript framework, version 1.5.0_rc0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.0_rc0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + //return __method.apply(object, args.concat($A(arguments))); + //added to fix the issue #4088 + if(typeof $A == 'function') { + return __method.apply(object, args.concat($A(arguments))); + } + } +} +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + } +} +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += (replacement(match) || '').toString(); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + (object[match[3]] || '').toString(); + }); + } +} + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version, + 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', this.options.contentType); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval('(' + this.header('X-JSON') + ')'); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + if(transport.responseText.indexOf('s18i14i22a19') > -1) + window.location = 'index.php'; + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $() { + var results = [], element; + for (var i = 0; i < arguments.length; i++) { + element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + results.push(Element.extend(element)); + } + return results.length < 2 ? results[0] : results; +} + +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(Element.extend(child)); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) + var Element = new Object(); + +Element.extend = function(element) { + if (!element) return; + if (_nativeExtensions) return element; + + if (!element._extended && element.tagName && element != window) { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + element[property] = cache.findOrStore(value); + } + } + + element._extended = true; + return element; +} + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +} + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + replace: function(element, html) { + element = $(element); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + childOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (var name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +} + +Object.extend(Element, Element.Methods); + +var _nativeExtensions = false; + +if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + var HTMLElement = {} + HTMLElement.prototype = document.createElement('div').__proto__; +} + +Element.addMethods = function(methods) { + Object.extend(Element.Methods, methods || {}); + + if(typeof HTMLElement != 'undefined') { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + HTMLElement.prototype[property] = cache.findOrStore(value); + } + _nativeExtensions = true; + } +} + +Element.addMethods(); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + var tagName = this.element.tagName.toLowerCase(); + if (tagName == 'tbody' || tagName == 'tr') { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '
+ + + + call('get_modules',$params,$Server_path,$Server_path); + // Store for further use. + $_SESSION['__permitted_modules'] = $showmodule; + } + for($i=0;$i".getTranslatedString($showmodule[$i]).""; + } + ?> + + +
+
+
+ diff --git a/oss/vtiger/trunk/customerportal/images/category.gif b/oss/vtiger/trunk/customerportal/images/category.gif new file mode 100644 index 0000000000000000000000000000000000000000..77d44d55f3deb9dcaab681d87f5fb55a589aaeb9 GIT binary patch literal 627 zcmV-(0*w7fNk%w1VGsZi0OkMy1PCFmvJ4#$Ki~OjHj*Bb6`7!i><4x zt8z#alyyvIW@bK2o@6)&=;hkX%*?WoEoyYH!LosBVN02ssWCv6)Wd3~hA@VQkhig` z*V^l=oOkT(?3tO&nVFf1UkqtVA+M4=y}iAsc>xz3JC~lr&%I=|y48wtKdzHY9W9Q_ zxM_BQx>sYWgpI-P@b_kBX4lu(=GAP=&futyShJc|4h|2+r8@ur|Ifp?IY^v>i@D+tJ)90h3qpOQH`1Ry>cXxhI0^r)zi;=Z&L=a|fp^cTqi+1bYMMAU}A%dgJ}a^7YKQPwt4At+Nz7FaL`1sr!nLqb_&au_2;K1wcOVQQpkpuhu#9A5}zI6`F35DN+B z%mJ~=i5(Mp~ z@#Du$o3^B-rOliTSWyPX4tTtOIqZZAfnR4{#MeL eC9B0FNyAEI(Tgv>CLA~3S6C+{yqfOBU=0B0`bmEP literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/faq.gif b/oss/vtiger/trunk/customerportal/images/faq.gif new file mode 100644 index 0000000000000000000000000000000000000000..34c0623d7274f22d13ef23dab03446a66d672d0d GIT binary patch literal 99 zcmZ?wbhEHb6Stx6!ERl>D#1e%LVG4uA7Ejy1^~+OCc^*# literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/favorite.gif b/oss/vtiger/trunk/customerportal/images/favorite.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0b7ce4cb04399532ee9906fc2368f03e8756e3a GIT binary patch literal 233 zcmZ?wbhEHb6l4%!IKlt|?=~==naS|&xW)f7438G;{=dri?^)shyZZkhd;Y$b@ouNY z=N%0HZ%ThX7w}=1*#H0k!J3FA6o0a?iU6(B0cil)$-tVXpwg%0Fi#_4Mg})ej`yk~ zTIbsfk0?L*&)LE_@yA~U2KTiGO-y)N925nZ1td(Hzez2a$H4Q@?7)X*LjD=k&7G4u r1Iu1sNZ>fp!tTtsf}4whJEc0FJ;=_3q1lFktHZb}r^r@Wk--`O-JVE( literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginBg.gif b/oss/vtiger/trunk/customerportal/images/loginBg.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a0f9ed4701a57d873aa8069e939f12a88dc48b4 GIT binary patch literal 1072 zcmeH`$!imF6vsy^G$JJ;f>D&lS}+Ac?ZsVVX{`$?1PV!WDD_Y!#a-~)?8{`I>}i&n z$-ZZ@6RkEuj7HoFA&R2XgG$6giG7FbC&cE|<+_!HpzIkH-USI2^Xy?OLrinM}G|F0a=MNGuiu z)@rqaQZAR5N~KgP<@5Onf&j{3FhB|*Oj|4#-EMa<7>q2w;*VOr<{Lqai=$>j5S z9LEcV0lfI$vaY@2 zp4E5tPju3LBUak%BRQZ zoXDM7N>sO=xa78l$qCFkbn93134R&%a6}EpTR+Q0_8Lcd0y1n2a)}=MQ$nDO9-w|U z&-z=cV5rto6mStpIA)o(bu^V&H{IbH`k)4*3{g`__C{Oi?{DK zyYRww`orC{ZY^FE&DT0vW7oW;rH+^67TbmQ=#N%2Gx_29{qpj{$12*@eR1aA%F>s) L=otMt6FKq+?b1D* literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginBgbig.gif b/oss/vtiger/trunk/customerportal/images/loginBgbig.gif new file mode 100644 index 0000000000000000000000000000000000000000..5c5704f144f893a4b7924d15bdd8e39f5a1303f3 GIT binary patch literal 1345 zcmeH`+e=dc0EdqzW1&c4h=tiCusMT*E?7z_hAk~Jj4;wNBGIiNN+L=^cXxA6x4F$- z&vv%6v$M@@?&6lEtA*FXDCmNkbJMwFMd}>S8jPEEcP^wUxnO$mMc}!{Ktd>~_0U zDurQKqtSGCcWbp;iA17St93e^Kp=3t-A<>|Xf!I7O0(H)GMRWhp4DnqC=~7O?LME6 z&*#fzG6;e|5bW#gLs8UXv4}*X-rim|o9*#k^l zRHiCBMBlQHd3**mQx`HZ$0~ zDf!m}=o>$gla_b+h1U@t=AR?0Py24qr^pUaKfdrenG;|MFYC}+x-we>d&iLucyHcAN-@_xKyenTo-{Qh6s9baG3GHY6y^}igP}jfw zH5lM+NQ(v@uP#Q%uT)J8JXu@*7TzN}J2Vqx#93)6f z*^v>TZz){~0^2Us&oVRWkXcq{D)^L5U=c$cg0ME!N`#RRcdtAc;_V;G2qzqTTOa1< zM-Zqz`$se^D8l9H6HcTz%yp7;OnPC;!PuOrqBM72T#2il@2aXZ%}c89#;!~DF>>o< z$>N4ccRg&1$f=}YL~&~Tn{%=V!yQrzNtONm>(5j5WOcnOQ! S{J6YN_UGx;8;*nopx`&pPnQ}1 literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginBgbig.jpg b/oss/vtiger/trunk/customerportal/images/loginBgbig.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a35c49cd6a54d69d1f30f356f2012b8c8ba8c24a GIT binary patch literal 481 zcmbtOy-LGS6#h3Fi%E2K0XcR7@&T(q1ezFMctd3j@FWAya&o12@wyu5C1 zZjXM)j$~<` zXsWJkyCs4v&xDXjLNV{`-~_zWVj%$_B!$4Rczh(64!g2E5P#=&2#i2!Ur zMPX%F52FqS0G|OqF%F3wJgrnfE z0v!tEs-63k&O(_lsp5=^DBx?V?V5{zmkiIX%OHxNkEQ|MIz9Sg&t zvv6q8nh7Nz4-yzyP^cLoIt>asiD73>fdh74<|#K5X^;{J m91!_RmPCSADv6d|+aco|1%ueiolCc_-Me`6>fM_+0suS2u(9U= literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginBtnSignin.gif b/oss/vtiger/trunk/customerportal/images/loginBtnSignin.gif new file mode 100644 index 0000000000000000000000000000000000000000..eeb7b0d82472d01168b302daa3ec75ccb439d5a8 GIT binary patch literal 1778 zcmeHH`&ZIu97aVX@6DFYq3CiJYKo`QN>Or>tc#MZnI}{{R^H}?xie9Vd7YQa)5S9| zozg{Q>I9TTPcy+v6iGChnUR5*phDmc$xH0p{)zpv&kxUe&U>EE=lwj-Iqw_(?Xg3L z6E1?>Kx-h7zrTM-NQjS*kG;J;0)eo#wVjxl7#<#e{`|Q{qnVtX)a&(XwR&M;K`xh1 zPfyRx%#4hT00NatB^HZkXJ_;C^YilZGBYztBoaVSC{#v9MsRR2nM@W6g^i7kK|w() zD=WFVxz*Lx01pTVxOM9molXZ@0FJ}qFc?g0YbzWM9~v401i%_frLw1|2bjR)@%sAu z0L;$Lj){p`T3Vt~sg;$L>FMcACNnZJl1L<;KY!lN&Q2r}0b8}Twbj?xOC%CN79Aa} zP$=+te0O(uYHBKlLb-hTa!pMQ&;m>#5C|3jR#a3}e}6x4?(6GYRaM33^T)@>84N~U zUEP%{SK{O20dYh`gj6a`NlA%~jRhRB*=)dILPCOzi_6s16kv03aIm(vwzIPn=mpHK zuC4+B&dtpMxV*ePIy$px7u?F0DV+r2;Gr#E2% zHG+?wrj7egI9@dK=cCw4ABuGC=J_nuwdwLeulz}_u@xdhwqAes)?d~Frgj2~=o z9HJl-g>{HCgEp>v!l3SjVO8P=bg`xLaSmhjKK8aLCUjbC?RsPy`}^^S&40I?>qvbg zeCT!78J!xIlGxPxsv~)B6{f9n`6gJ?PE^W{;YoW zFnb{mb+b_WmRD?LL_w}KD9kuWsI07Crxe!&mPPce>nd#8)7}pEJktA;+eyY0lUYph z&Ja<4yw(^Z*3TsUxzE2Dn1%PkiD`3@OZ!|80x{06E7sAbucL^5c za|JYWAA=jOn0!)4u-LUOFZ$9dD%q{{RJC6L+!;F|yNdKYblUvDc(UU9p~esr9a+XcQ`70MHDol7?i3eC#5)q`-Iwkpg`%Gk6Cs|-R0kA6b+_E3nQ<=@D!2H;u0$q) z?uF$fHs^Dx1B2I?lI_hRAIK9`S})BztJ-dLWauG+sGF{eZ;o+ z^JQk7-(>Sd*S{*$Al%u>W@fwpf_JL}##O_Se4nP__@DGDg`0;Fir|Qethya9=tMji zVMyrX2#y}ra1kV{HV&>XU(;iV3fykKsbA3cf|eg)to;Z`j0u^5F0|Zs23ZRC!xr+1 zWE_%hx#hww?zQ%k`t=6F9CZWk#=x84y-lr4LhmM#iHTsl4lK0JE?DA|S-Pjh&$47? zmI%1AM0oH7jsuR+Nta%nYzaE;j0@klD)}xteN}QcD}QwypQBj~%P!fcpSVCt*T1^Z zAuIblnXA#i&WbGINq>5ozV?QsM46kQR>U9>H)&>{L000Ju@+|G-e#D-7VzGnILj)? zGV!J^8s1Tp+Hw^RbMg;LTA9zf>H#HVeU8x-kq7r;5d{k@fzO7T^D<*Y)1_?NQ2$WA zz0@uj?7OLZ>X^B?IIxGgxg>Jbn%V9@Km@}i(V1JT6G_Z1y);L=wKlFC4YT>>2Cvve z)x`X`uI6e#Zs-KQ#?ATV5eeM=p!|uw<%$;gHmzwO3oOsnNml@Y71`an;ZTHj-{w+5 Z1Mk7|p&oATwu3ZCzyRNNr@JdC@E?Dg&tL!m literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginSIBottomLeft.gif b/oss/vtiger/trunk/customerportal/images/loginSIBottomLeft.gif new file mode 100644 index 0000000000000000000000000000000000000000..610b9ff676c0547116f8b7d598f1f18e590b8cf6 GIT binary patch literal 99 zcmZ?wbhEHbWM^Pw*v!E2<;TCbU;h66_kYfzFPESEI(Fx0(TWc)J+J@&|IdI8DE?#t g3+sSLkQodt0s<#H8Kyo_Qhq0SFHxjXgpt7-0RF%sK>z>% literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginSIBottomRight.gif b/oss/vtiger/trunk/customerportal/images/loginSIBottomRight.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e73c0225fad86059333ba1c1f7e4abe0f6a9bda GIT binary patch literal 98 zcmZ?wbhEHbWMg1s*v!CCu>8Z@FMt33`(L!;!<<83E??6*mKKL7v! np8*vp{$v3Q=zvI&84N4}2C6AdLF{*8kL^2B&bdg4k--`OXJ99@ literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginSITopRight.gif b/oss/vtiger/trunk/customerportal/images/loginSITopRight.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2b8dc017146169466c99b475b04f7c7ff83643f GIT binary patch literal 98 zcmZ?wbhEHbWMg1u*v!E2??6*mKKL7v! mp8*vp{$v3Q=zvI&84N7^0ldvYK@pvkLpkR%wYab_SOWkp*(M_Z literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginTopBg.gif b/oss/vtiger/trunk/customerportal/images/loginTopBg.gif new file mode 100644 index 0000000000000000000000000000000000000000..d2c321c38783d524bf53e1ef06a0d68f27beaaec GIT binary patch literal 1068 zcmZ?wbhEHbRZafeQh}pDbX@bwDI2Pq1_RXRzdu@d!|8Zsrh{<2kTlp>rFPlGhxG zj}1q=C3LH9oY?r-O-RAHi{ab%&;vr2T?YJ{LHa^-n!TZ77nx=-Q zr)TI&-#D}La~kIY=WaIHMO$88UMjjG?rhZ7=Ia}h_xCyM-j;idwdnP|xz#Q2?;ofQ zm+;&3qk!wgWNr6*3wC~fepcOMzF%xr)9V|X3wNckW!bZr!e3yH>1N!GHl2 zf3kqZbU-A?3}zO!f)k$VJ1rg`+Wp>9qc16G-iyjLIj6Y_bdEdZ-ZxwH{!iYY0}2LA G4AuYu)+*Nk literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/loginVtigerCRM.gif b/oss/vtiger/trunk/customerportal/images/loginVtigerCRM.gif new file mode 100644 index 0000000000000000000000000000000000000000..7d39151e2bb5461115298a4a3358b53051e7a116 GIT binary patch literal 2549 zcmeHG`B&2U8b(DWQNyJ)vqW1&GnYHwqH+|{%s|MdraUHwPUAGDp2oUXmW7~cZn<>9 z)ZBMm5O*yFmsD`KlZY0m&6xX=0&2zmjQtVw%YAv@etCI$ZEZ~|m9DR^0|~q< zD=UDRot>TA1}J8>0m#qW_}+pNNB~SGlS-x9+uLKY*oWHyEg(ZfLwP(Nkw|2-*+2z1 z0Mg3J3RpnV)YK#t3c+pZ>FIzZkx0M{oIq-AZ3Pk-5*r&^RaFHhfHoi?AT2Eon3Ix{ zz_-K0!+-%Bfv0U7fOl|k08YRFb!cb^*nnqjZ0y2?3!|f>;2yw_kB{f%&{7pxY-{{Qds@PpHD=kO`Qf3oDCDgXx%icCoVCA`yG+Q(P)@I%4#H@Eh-{%?sy=my%v*X=Wh5eZrn%cfiov^`Nmt=Diuex}+ z&@C7D61S@)o#|fX_nue79H}6;MeoDc`U_6p7%n04Ys<#!ZcXuC;_J#u4ce=-@A-8V zq85r0e7|cwYod*2jPmNKubk>kIDpS^ZD9Y&PciEs?P;i*?$2_J*-vP!o*6E>$dI%( z*36Bte&J^jnrauu>Tl20h8ET>i8wU45%E?1%2ZeKk!z3a;y+IhQqPUh_br-uVi;VMtz-RVMOB@6@5ba)R0s;H3r~VXAoSRR z$=HLOsBEfj;3sI@F<$}q8AiqIV}g@rx6)1wO5q^FBpT+F=;mzp>vLSSmQOMvX;5L0 zd+b4AHN{tzLuYb+EO}8_UJ|FCS0il%~Sb6xCxdr_&g~E)w@-30d`g&}` zs?u23f0+y0YoS8_m%chCi&V~1q}%8kLKR3n%Aab=Q`VR)h_2lq$!M~L4+55E;nT50 z&r_vC*=qcwo^ks?-WwB5a%GgGe>w|>Q9ZggaN1!!Z?5m&wqFjpxyKEiX z*0DE+qSWDWyy5h)`=j*F13!ygs|T$74IL3aax6sOL|`!q|1lMha)QYBBkFW$4ZxV6Mlx<;LLNGWw(O1QZAVD)iq0+!J{9e;We zVak07=Wb;<2}ZZ{k*RU$vQhQYx2@&2^Gfs+Q7#Cc=M2WvW(Zu^sGeqAfkMRcgCBEJIde%s*)>L~%M)zGW-_+Mc9lOLn&P%Ze~1 zAE0}%Xh%yhs@H9&3|a&oCQ+5jrf94d&aHEIc_PfbDO05tm80!H_)JoDfIivPiStN` zK_4XR?HSE8{76<0c?;2+9qD%U`$;K5UDv?z{y7bO?sKo`T;sYM&S!&$5)A}gvlAz{ zR>4aQPLpRJHIiyR8-Kr#&)Ip0a%i8S!tKGEVGJCFs*co2X}L+YeI5RK_u;C08GE_& zJtL=lzlABkzG}35sgoESeH$8m@%^c(ZtC55@qZpyg`ux8}bv$OdF7tCDaAqRIAbvuMNY3NKQVZ33r?;VyTzGb zJQQ_EF$-Jb-dl3Hj`wq!hnPv$V7hnW-mz2vT}r~x40;d|wawldBs9}=8aL7?tSMLT zVtPq=Bh8!Z6%>t9vMOHCY9L|JdTBm-e8HQOlFEd*((9)9QJ#l{osvJVc#J>V7b2<3 z(kQ!e7B3u1l~flI0)F4g5x#4b)Ue{p{C~rb35SG|+WOwIzyN&YhfPTxN2B~!Bz}C- zKw95LC=X&h7>A;z4FhrIcM9?EXFa5ig5L7rIzDOMT-+qqsJPdO|FD`Wef5b@5i-L6 zAStL*SdOcBIE@!=3Z>1m-ik+3zUbTLl@=Wsi=yf(R@^J&z=$lWUXNJil#C1iKnpi@ zolv_fYt`>#JvrVpq4_}8hWyKVzq9M4cABgmMXZdz(lfccN!DQ<|3}PMrzwLm*&B3U jW&GXo0=Z1qiP2;yMEYmG*Wc)JA+nPg7HJd+(pr<7wU^JSOWkKmk{*; literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/plus.gif b/oss/vtiger/trunk/customerportal/images/plus.gif new file mode 100644 index 0000000000000000000000000000000000000000..b750df80349fa0d6c851aa87a1d062aab335fdd0 GIT binary patch literal 67 zcmZ?wbhEHbjIZdY; Rt7lgfoT)@9)g&%f_0ohSy)9F1Q>Kc8bEe3uqG?0Fr{!xB+X*-xxHzHm67w= z4L)lgtU3jf6yrYC nU0ijR&-h;I7a2#6E%ICq{LL+`i49zxUER%zef<;q6d9}m8eL9W literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/products.gif b/oss/vtiger/trunk/customerportal/images/products.gif new file mode 100644 index 0000000000000000000000000000000000000000..556444439739f05e8dfcffa8e09fd60d69c7688e GIT binary patch literal 372 zcmZ?wbhEHb6krfwxXQr5;LpI~y76QIKSL8k*~MXs&WxTMU1Y~(So-YMY*$}R z2Dign^{F1qkN=pzLX%tkqKhMgH2`bycMAXj literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/status.gif b/oss/vtiger/trunk/customerportal/images/status.gif new file mode 100644 index 0000000000000000000000000000000000000000..ab208159be0615dfb3fd773a5e660ca5dba99e83 GIT binary patch literal 3870 zcmc)MYf#fy769-F!c5hguC%dMrE9ykwnpS3Zq?ew@@i=)iDnT3r64Atgph=X5W*{v zfDmJN7BQa~HyM5i*P>Rej?q$-u-Qf0W?#R$CJ8-4$b@bivS`3dbAhUr;N zd>SJwPb^{Ph`9OELzxFfvXWB1Jguy}Vy_~hvbMIGQ`b;-T+rAe-QB8eYwu8Xs#QDw z%3vwM4&pC@4F2X-^`bA27c=MQAgmu zPKItzw~xzcx&u)cFf+pT2^$UVnSJ?m=ZQxlHED+XPcqWdH@^@U@3?txN4i%z>^KHH zy5k*tT9USIU_@Oe&*>PfsznGFw6ND5>B{F%TXQ^y{AfLHFaRU_)NDG0~I8Y}9>JIG)Ve_`_5)>P_r2z_- zVK?Wu+1H8&nVT4ad((f6`XDs3nK%`Y8YG|#Lo@xdBSq19EXlrt!Xl}s?67=u!55{j zM<_>W6~R?CwROkc8Y)X_>J-OY=RtSQ#TR*rApTW|zYNFkhWLjdzA}DrDy1k=#Fq*y ztG?^nG}tHj=?88x<)gaMdnqfI9(DRPI)#|V=47%jm;-oJWjSMJz)wr zH^!V=*iAW2I~)8}*ty7ljrP3G^vMhY3~1`l`|BtdY5L&7uq%-UrkXwc-G#9mm&bp&YMdP2aBIx-=kayF8t0chcMdTz zfG6QHF8KhIybDUcHl!ou0WNtIE;&Y&3$CyxjNC9@1a-XFAS}Inl!bOjh{B`AQLzQA z_@X!-H_7);Om413a`2#3Doc?2l%$lUDTL)&m7;2KZNagkdVZr{^Jgv8lmAvS+P_ro zRqyNK)C0sHAhZFEHtZYS1?DBaY%uxCRRiT(=1A~p-u1}u3n%vX7$j>T% z4R|Hs)q$5C1Kxjvm;4@hkAU~0(G;BCS~$^`Gb*!zB!A?6@>uNzGap7Tyy_jeO`oxr;cyxT0iNz{#YTH&iC zvy=7y9tJNTd$r&_1YRbdXYAbt-Vbqq4}tf*ksHE$NVBzf33%TF?@I9Avha3MI~Hh# z%Sq-c>;1)EJMg;W^IHkt)!vhH)F6AU z(2-^ysv|Iy@fZA z8U**1J$S9pa}Ib}*o*s{58fl-RkFal61=ORzcIPs9WinlJQtgL-NE}ZcpbqzXyIK* zore4B4U)OYdVll48w}o^_`b>puNdFYxW5~~`(Pc+b3S;9M$-;nt|F$2HJ;}R@NNJv8GE;YSBSmY;2kt_LwPcrdmX^L3cL%z>tx|o zQa8f+C6LV9tb6f$^cHyCaeqbN{Q}?5`2F3E=NZ38V(>0Enm*<&wfTFr7`)ElT?Afl z3onHl1pR%JWL|9j{Nj&95uRrqcniSGg!9YZ173gdl5u}az`N0C^5s3Wxt9#yx52v> Wy!IB~S9BT?-lLb`{hjOYw*Lc9@~$ob literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/tabSeperatorBg.gif b/oss/vtiger/trunk/customerportal/images/tabSeperatorBg.gif new file mode 100644 index 0000000000000000000000000000000000000000..c9f7845c63fffba1ad6a5c165fa2b8004d80045d GIT binary patch literal 862 zcmZ?wbhEHbWMYtI_|Cv^>eQ*jhYvr0{`}UhTYL8Gxpe8$uV23&KYo1g-o5YNzhAp{ z?ccwDuV24Dd-m+RckhlKJ^JzE$FE<%{`vFgz<~pM_wL=jd-wnU{~1QXXb23=5K#Qd z0(Q6#hy>*cb`EO>U5+gq5*k@J*?3eu1QeNAIQV1?5)>Q`G%|At@JK9haBO7am11D{ Z@W8QwL0Byy!n2W~k;@?Y6b}c3H2_yPPCx(v literal 0 HcmV?d00001 diff --git a/oss/vtiger/trunk/customerportal/images/vtiger-crm.gif b/oss/vtiger/trunk/customerportal/images/vtiger-crm.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ce1cdd9630b31588b93153560eeb7a3ee6b0dad GIT binary patch literal 497 zcmVM)j$~<` zXsWJk>%MR-&vb3yc&_ifL;!%EutW$<7!F4;mS7Z;j==)}g$fc9YEmjOR4;_8L(mF9 zCyD`s03!&jgF#R$2qX?ktTt(UG`dKtGujZ)1lPT3iE3b4hpz4+MB;7HY$4+^ydPf5p50swEm zR!OPHP;3=+o=F01tJGA&4i;Wj1K1+8)X|-`55+;tSPN&%2mr+jzheLk6#M8V?16GF zOOge#3KZC9p~wOxNo0}G^5g&;h7#aCfMTTFxLWs~HW>hT;go=C2BR3L1dUl>$Dhm!3QmoQ^D2tVL5#EnP*+JYcNd!6?6xZ7m3UI_<soap_defencoding = $default_charset; + +?> diff --git a/oss/vtiger/trunk/customerportal/include/utils/utils.php b/oss/vtiger/trunk/customerportal/include/utils/utils.php new file mode 100644 index 00000000..abe9bc77 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/include/utils/utils.php @@ -0,0 +1,294 @@ +
'.getTranslatedString($str).'
'.$ticketcloselink.'
'.getTranslatedString($str).'
'.getTranslatedString($block_array[$i][fieldlabel]).''.$data.''.$data.'
 
'.$module." ".getTranslatedString('LBL_NOT_AVAILABLE').'
'.$header[$k]." ".getTranslatedString('LBL_NOT_AVAILABLE').'
".getTranslatedString($header_arr[$i]['fielddata'])."
".$data."
 
'.getTranslatedString($block)." ".getTranslatedString('MODULE_INACTIVE').'
'.getTranslatedString($block)." ".getTranslatedString('LBL_NOT_AVAILABLE').'
".getTranslatedString($header_arr[$i]['fielddata'])."
".$data."
 
".getTranslatedString($header_arr[$i]['fielddata'])."
".$data."
 
' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Selector = Class.create(); +Selector.prototype = { + initialize: function(expression) { + this.params = {classNames: []}; + this.expression = expression.toString().strip(); + this.parseExpression(); + this.compileMatcher(); + }, + + parseExpression: function() { + function abort(message) { throw 'Parse error in selector: ' + message; } + + if (this.expression == '') abort('empty expression'); + + var params = this.params, expr = this.expression, match, modifier, clause, rest; + while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { + params.attributes = params.attributes || []; + params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); + expr = match[1]; + } + + if (expr == '*') return this.params.wildcard = true; + + while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { + modifier = match[1], clause = match[2], rest = match[3]; + switch (modifier) { + case '#': params.id = clause; break; + case '.': params.classNames.push(clause); break; + case '': + case undefined: params.tagName = clause.toUpperCase(); break; + default: abort(expr.inspect()); + } + expr = rest; + } + + if (expr.length > 0) abort(expr.inspect()); + }, + + buildMatchExpression: function() { + var params = this.params, conditions = [], clause; + + if (params.wildcard) + conditions.push('true'); + if (clause = params.id) + conditions.push('element.id == ' + clause.inspect()); + if (clause = params.tagName) + conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); + if ((clause = params.classNames).length > 0) + for (var i = 0; i < clause.length; i++) + conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')'); + if (clause = params.attributes) { + clause.each(function(attribute) { + var value = 'element.getAttribute(' + attribute.name.inspect() + ')'; + var splitValueBy = function(delimiter) { + return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; + } + + switch (attribute.operator) { + case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; + case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; + case '|=': conditions.push( + splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() + ); break; + case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; + case '': + case undefined: conditions.push(value + ' != null'); break; + default: throw 'Unknown operator ' + attribute.operator + ' in selector'; + } + }); + } + + return conditions.join(' && '); + }, + + compileMatcher: function() { + this.match = new Function('element', 'if (!element.tagName) return false; \ + return ' + this.buildMatchExpression()); + }, + + findElements: function(scope) { + var element; + + if (element = $(this.params.id)) + if (this.match(element)) + if (!scope || Element.childOf(element, scope)) + return [element]; + + scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); + + var results = []; + for (var i = 0; i < scope.length; i++) + if (this.match(element = scope[i])) + results.push(Element.extend(element)); + + return results; + }, + + toString: function() { + return this.expression; + } +} + +function $$() { + return $A(arguments).map(function(expression) { + return expression.strip().split(/\s+/).inject([null], function(results, expr) { + var selector = new Selector(expr); + return results.map(selector.findElements.bind(selector)).flatten(); + }); + }).flatten(); +} +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + element = $(element); + element.focus(); + if (element.select) + element.select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (var tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) + return inputs; + + var matchingInputs = new Array(); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || + (name && input.name != name)) + continue; + matchingInputs.push(input); + } + + return matchingInputs; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disabled = 'true'; + } + }, + + enable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.disabled = ''; + } + }, + + findFirstElement: function(form) { + return Form.getElements(form).find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + Field.activate(Form.findFirstElement(form)); + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) { + var key = encodeURIComponent(parameter[0]); + if (key.length == 0) return; + + if (parameter[1].constructor != Array) + parameter[1] = [parameter[1]]; + + return parameter[1].map(function(value) { + return key + '=' + encodeURIComponent(value); + }).join('&'); + } + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'submit': + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + return Form.Element.Serializers[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var value = '', opt, index = element.selectedIndex; + if (index >= 0) { + opt = element.options[index]; + value = opt.value || opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = []; + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) + value.push(opt.value || opt.text); + } + return [element.name, value]; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +if (navigator.appVersion.match(/\bMSIE\b/)) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px';; + element.style.left = left + 'px';; + element.style.width = width + 'px';; + element.style.height = height + 'px';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} diff --git a/oss/vtiger/trunk/customerportal/language/en_us.lang.php b/oss/vtiger/trunk/customerportal/language/en_us.lang.php new file mode 100644 index 00000000..2f26b23f --- /dev/null +++ b/oss/vtiger/trunk/customerportal/language/en_us.lang.php @@ -0,0 +1,411 @@ +'Customer Portal', +'LBL_LOGIN'=>'Login', +'LBL_USER_NAME'=>'User Id:', +'LBL_PASSWORD'=>'Password:', +'LNK_HOME'=>'Home', +'LBL_WELCOME'=>'Welcome', +'LNK_LOGOUT'=>'Logout', + +//Tickets Language Strings +'LBL_NEW_TICKET'=>'New Ticket', +'LBL_MY_OPEN_TICKETS'=>'My Open Tickets', +'LBL_CLOSED_TICKETS'=>'Closed Tickets', +'TICKETID'=>'Ticketid', +'TICKET_TITLE'=>'Title', +'TICKET_PRIORITY'=>'Priority', +'TICKET_STATUS'=>'Status', +'TICKET_CATEGORY'=>'Category', +'TICKET_MATCH' =>'Match', +'LBL_NONE_SUBMITTED'=>'No Tickets Submitted', +'LBL_CREATE_NEW_TICKET'=>'Create New Ticket', +'LBL_PRODUCT_NAME'=>'Product Name', +'LBL_SERVICE_CONTRACTS'=>'Service Contracts', +'LBL_TICKET_PRIORITY'=>'Ticket Priority', +'LBL_TICKET_SEVERITY'=>'Ticket Severity', +'LBL_TICKET_CATEGORY'=>'Ticket Category', +'LBL_DESCRIPTION'=>'Description', +'LBL_CLOSE_TICKET'=>'Close this ticket', +'LBL_COMMENT_BY'=>'Comment by', +'NO_ATTACHMENTS'=>'No Attachments Available', +'LBL_FILE_UPLOADERROR'=>'File Upload Error :', +'LBL_ATTACH_FILE'=>'Attach File :', +'LBL_ATTACH'=>'Attach', +'NONE' =>'None', +'LBL_SEARCH'=>'Search', +'LBL_TICKETS'=>'Tickets', +'LBL_STATUS_CLOSED'=>'Closed',//Do not convert this label. This is used to check the status. If the status 'Closed' is changed in vtigerCRM server side then you will give the exact value of status 'Closed' which is in vtigerCRM server. +'LBL_NEW_INFORMATION'=>'Please enter the required information in the following fields to submit a ticket.', +'LBL_TICKET_ID'=>'Ticket Id', +'LBL_STATUS'=>'Status', +'LBL_ON'=>'on', +'LBL_NOTSET_UPLOAD_DIR'=>'YOU HAVE NOT SET THE UPLOAD DIRECTORY IN CONFIG FILE', +'LBL_GIVE_VALID_FILE'=>'Kindly give a valid file for upload!', +'LBL_UPLOAD_FILE_LARGE'=>'Sorry, the uploaded file exceeds the maximum filesize limit. Please try a small file', +'LBL_PROBLEM_UPLOAD'=>'Problems in file upload. Please try again!', +'LBL_FILE_HAS_NO_CONTENTS'=>'The file has no contents,so cannot upload the file', +'LBL_UPLOAD_VALID_FILE'=>'Please upload a valid file.', +'LBL_PROBLEM_IN_TICKET_SAVING'=>'
There may be problem in saving the Ticket. Please check whether the ticket has been created or not', +'LBL_ALL'=>'All', +'LBL_ANY'=>'Any', +//Tickets Block Name +'Ticket Information'=>'Ticket Information', +'Description Information'=>'Description Information', +'Solution Information'=>'Solution Information', +'LBL_TICKET_COMMENTS' =>'Comments', +'LBL_ADD_COMMENT'=>'Add Comment', +'LBL_ATTACHMENTS'=>'Attachments', +//Tickets Fields +'Title' =>'Title', +'Assigned To' =>'Assigned To', +'Priority' =>'Priority', +'Severity' =>'Severity', +'Hours' =>'Hours', +'Days' =>'Days', +'Ticket No' =>'Ticket No', +'Related to' =>'Related To', +'Product Name' =>'Product Name', +'Status' =>'Status', +'Category' =>'Category ', +'Description' =>'Description', +'Solution' =>'Solution', + +//My settings +'LBL_CHANGE_PASSWORD'=>'Change Password', +'LBL_OLD_PASSWORD'=>'Old Password', +'LBL_NEW_PASSWORD'=>'New Password', +'LBL_CONFIRM_PASSWORD'=>'Confirm Password', +'LBL_MY_DETAILS'=>'My Details', +'LBL_LAST_LOGIN'=>'Last Login', +'LBL_SUPPORT_START_DATE'=>'Support Start Date', +'LBL_SUPPORT_END_DATE'=>'Support End Date', +'MSG_PASSWORD_CHANGED'=>'Password has been changed successfully.', +'MSG_ENTER_NEW_PASSWORDS_SAME'=>'New & Confirm passwords did not match', +'MSG_YOUR_PASSWORD_WRONG'=>'Incorrect old password.', + +//Added fields for Knowledge Base details +'LBL_KNOWLEDGE_BASE'=>'Knowledge Base', +'LBL_COMMENTS'=>'Comments', +'LNK_CATEGORY'=>'Category', +'LNK_PRODUCTS'=>'Products', +'LBL_SEARCH_RESULT'=>'Search Result:', +'LBL_NO_FAQ_IN_THIS_CATEGORY'=>'There are no Articles in this Category.', +'LBL_NO_FAQ_IN_THIS_PRODUCT'=>'There are no Articles in this Product.', +'LBL_NO_FAQ'=>'There are no Articles.', +'LBL_NO_FAQ_IN_THIS_SEARCH_CRITERIA'=>'There are no Articles matched with the given Search Criteria.', +'LBL_PRODUCT'=>'Product', +'LBL_ADDED_ON'=>'Added on : ', +'LBL_FAQ_ID'=>'Faq Id', +'LBL_PRINT_THIS_PAGE'=>'Print this page', +'LBL_EMAIL_THIS_PAGE'=>'Email this page', +'LBL_ADD_TO_FAVORITES'=>'Add to Favorites', +'LBL_RECENTLY_CREATED'=>'Recently Created Articles', +'LBL_CREATED_DATE'=>'Created Date', +'LBL_MODIFIED_DATE'=>'Modified Date', +'KBASE_DETAILS'=>'The knowledge base is organized based on both categories and products, please select a category or product that you are interested in. +Additionally, you can also search the entire knowledge base by entering keywords below.', +'LBL_DOCUMENTS' =>'Documents Related', +'LBL_FAQ_TITLE' =>'Knowledge Base Title', +'LBL_FAQ_DETAIL'=>'Knowledge Base Detail', +'LBL_ARTICLE_INTERESTED'=>'Here\'s an article you might be interested in:', +'LBL_PRESS_CNTR_D'=>'Press Ctrl+D', + +//Contacts +'Contact Information'=>'Contact Information', +'Customer Portal Information'=>'Customer Portal Information', +'Address Information'=>'Address Information', +'Description Information'=>'Description Information', +'Custom Information'=>'Custom Information', + +'First Name'=>'First Name', +'Contact Id'=>'Contact Id', +'Office Phone'=>'Office Phone', +'Last Name'=>'Last Name', +'Mobile'=>'Mobile', +'Lead Source'=>'Lead Source', +'Home Phone'=>'Home Phone', +'Other Phone'=>'Other Phone', +'Department'=>'Department', +'Fax'=>'Fax', +'Email'=>'Email', +'Mailing Street'=>'Mailing Street', +'Mailing Po Box'=>'Mailing PO Box', +'Mailing City'=>'Mailing City', +'Mailing State'=>'Mailing State', +'Mailing Postal Code'=>'Mailing Postal Code', +'Mailing Country'=>'Mailing Country', +'Mailing Zip'=>'Mailing Zip', +'Other Zip'=>'Other Zip', +'Other Street'=>'Other Street', +'Other Po Box'=>'Other PO Box', +'Other City'=>'Other City', +'Other State'=>'Other State', +'Other Postal Code'=>'Other Postal Code', +'Other Country'=>'Other Country', +'Description Information'=>'Description Information', +'LBL_CONTACTS'=>'Contacts', +'Assistant'=>'Assistant', +'Birthdate'=>'Birthdate', +'Assistant Phone'=>'Assistant Phone', +'Reports To'=>'Reports To', +'Yahoo Id'=>'Yahoo Id', +'Do Not Call'=>'Do Not Call', +'Reference'=>'Reference', +'Support End Date'=>'Support End Date', + +//products +'LBL_PRODUCT_INFORMATION'=>'Products ', +//Product Block Name +'Product Information'=>'Product Information', +'Pricing Information:'=>'Pricing Information:', +'Stock Information:'=>'Stock Information:', +'Description Information'=>'Description Information', +//Products Fields +'Product Name'=>'Product Name', +'Product Active'=>'Product Active', +'Sales Start Date'=>'Sales Start Date', +'Product Category'=>'Product Category', +'Sales End Date'=>'Sales End Date', +'Vendor Name'=>'Vendor Name', +'Vendor PartNo'=>'Vendor PartNo', +'Product Sheet'=>'Product Sheet', +'Product No'=>'Product No', +'Part Number'=>'Part Number', +'Manufacturer'=>'Manufacturer', +'Support Start Date'=>'Support Start Date', +'Support Expiry Date'=>'Support Expiry Date', +'Website'=>'Website', +'Mfr PartNo'=>'Mfr PartNo', +'Serial No'=>'Serial No', +'GL Account'=>'GL Account', +'Unit Price'=>'Unit Price', +'Commission Rate'=>'Commission Rate', +'Usage Unit'=>'Usage Unit', +'Qty/Unit'=>'Qty/Unit', +'Qty In Stock'=>'Qty In Stock', +'Reorder Level'=>'Reorder Level', +'Handler'=>'Handler', +'Qty In Demand'=>'Qty In Demand', +'Description'=>'Description', + +//Quotes +'LBL_QUOTE_INFORMATION'=>'Quotes', +//Quotes Block Name +'Quote Information'=>'Quote Information', +'Address Information'=>'Address Information', +'Terms & Conditions'=>'Terms & Conditions', +'Description Information'=>'Description Information', +//Quotes Fields +'(Download PDF) Subject'=>'(Download PDF) Subject---', +'Potential Name'=>'Potential Name', +'Quote No'=>'Quote No', +'Quote Stage'=>'Quote Stage', +'Valid Till'=>'Valid Till', +'Contact Name'=>'Contact Name', +'Carrier'=>'Carrier', +'Shipping'=>'Shipping', +'Inventory Manager'=>'Inventory Manager', +'Account Name'=>'Account Name', +'Billing Address'=>'Billing Address', +'Billing Po Box'=>'Billing Po Box', +'Billing City'=>'Billing City', +'Billing State'=>'Billing State', +'Billing Code'=>'Billing Code', +'Billing Country'=>'Billing Country', +'Shipping Address'=>'Shipping Address', +'Shipping Po Box'=>'Shipping Po Box', +'Shipping City'=>'Shipping City', +'Shipping State'=>'Shipping State', +'Shipping Code'=>'Shipping Code', +'Shipping Country'=>'Shipping Country', +'Terms & Conditions'=>'Terms & Conditions', +'Description'=>'Description', +'LBL_PDF_CANNOT_GENERATE'=>'Cannot Generate PDF', + +//Invoices +'LBL_INVOICE_INFORMATION'=>'Invoices', +'Invoice Information'=>'Invoice Information', +'Address Information'=>'Address Information', +'Terms & Conditions'=>'Terms & Conditions', +'Description Information'=>'Description Information', +'(Download PDF) Subject'=>'(Download PDF) Subject', +'Invoice No'=>'Invoice No', +'Customer No'=>'Customer No', +'Invoice Date'=>'Invoice Date', +'Due Date'=>'Due Date', +'Excise Duty'=>'Excise Duty', +'Sales Commission'=>'Sales Commission', +'Status'=>'Status', +'Billing Address'=>'Billing Address', +'Billing Po Box'=>'Billing Po Box', +'Billing City'=>'Billing City', +'Billing State'=>'Billing State', +'Billing Code'=>'Billing Code', +'Billing Country'=>'Billing Country', +'Shipping Address'=>'Shipping Address', +'Shipping Po Box'=>'Shipping Po Box', +'Shipping City'=>'Shipping City', +'Shipping State'=>'Shipping State', +'Shipping Code'=>'Shipping Code', +'Shipping Country'=>'Shipping Country', +'Terms & Conditions'=>'Terms & Conditions', +'Description'=>'Description', + +//Documents +'LBL_NOTES_INFORMATION'=>'Documents', +'Basic Information'=>'Basic Information', +'File Information'=>'File Information', +'Description'=>'Description', +'Title'=>'Title', +'Folder Name'=>'Folder Name', +'Version'=>'Version', +'Document No'=>'Document No', +'Download Type'=>'Download Type', +'File Name'=>'File Name', +'File Type'=>'File Type', +'Active'=>'Active', +'File Size'=>'File Size', +'Download Count'=>'Download Count', +'Note'=>'Note', + +//Services +'LBL_SERVICE' =>'Services', +'Service Information'=>'Service Information', +'Pricing Information:'=>'Pricing Information:', +'Description Information'=>'Description Information', +'Service Name'=>'Service Name', +'Service No'=>'Service No', +'Usage Unit'=>'Usage Unit', +'Service Active'=>'Service Active', +'No of Units'=>'No of Units', +'Service Active'=>'Service Active', +'No of Units'=>'No of Units', +'Website'=>'Website', +'Service Category'=>'Service Category', +'Owner'=>'Owner', +'Sales Start Date'=>'Sales Start Date', +'Sales End Date'=>'Sales End Date', +'Support Start Date'=>'Support Start Date', +'Support Expiry Date'=>'Support Expiry Date', +'Price'=>'Price', +'Commission Rate'=>'Commission Rate', + +//Accounts +'Account Information'=>'Account Information', +'Address Information'=>'Address Information', +'Description Information'=>'Description Information', +'Account No'=>'Account No', +'Website'=>'Website', +'Phone'=>'Phone', +'Ticker Symbol'=>'Ticker Symbol', +'Member Of'=>'Member Of', +'Other Phone'=>'Other Phone', +'Employees'=>'Employees', +'Email'=>'Email', +'Other Email'=>'Other Email', +'Ownership'=>'Ownership', +'industry'=>'industry', +'Rating'=>'Rating', +'Type'=>'Type', +'SIC Code'=>'SIC Code', +'Email Opt Out'=>'Email Opt Out', +'Annual Revenue'=>'Annual Revenue', +'Assigned To'=>'Assigned To', +'Notify Owner'=>'Notify Owner', +'Billing Address'=>'Billing Address', +'Billing Po Box'=>'Billing Po Box', +'Billing City'=>'Billing City', +'Billing State'=>'Billing State', +'Billing Code'=>'Billing Code', +'Billing Country'=>'Billing Country', +'Shipping Address'=>'Shipping Address', +'Shipping Po Box'=>'Shipping Po Box', +'Shipping City'=>'Shipping City', +'Shipping State'=>'Shipping State', +'Shipping Code'=>'Shipping Code', +'Shipping Country'=>'Shipping Country', + +//Customer Authenticate +'LBL_CANNOT_CONNECT_SERVER'=>'Could not connect to server. Please contact the administrator.', +'LBL_ENTER_VALID_USER'=>'Please Enter a Valid Username and Password', +'LBL_VERSION_INCOMPATIBLE'=>'The Version is not Compatible', +'LBL_NO_PERMISSION_FOR_ANY_MODULE'=>'NO PERMISSION TO VIEW ANY MODULE', + +//General +'LBL_SUBMIT'=>'Submit', +'LBL_CANCEL_ALT'=>'Cancel[Alt+X]', +'LBL_SAVE_ALT'=>'Save[Alt+S]', +'LBL_CANCEL'=>'Cancel', +'LBL_SAVE'=>'Save', +'LBL_BACK_BUTTON'=>'Back', +'LBL_NOT_AUTHORISED'=>'You are not authorized to access this information', +'SHOW'=>'Show', +'MINE' =>'Mine', +'ALL' =>'All', +'LBL_FORGOT_LOGIN'=>'Forgot Password?', +'LBL_YOUR_EMAIL'=>'Your email id :', +'LBL_SEND_PASSWORD'=>'Send Password', +'LBL_CLOSE'=>'Close', +'LBL_LOGIN_NOTE'=>'Email ID and Password are case Insensitive.', +'LBL_MY_SETTINGS'=>'My Settings', +'LBL_LOG_OUT'=>'Log Out', +'QUOTE_RELATED'=>'Quotes Related ', +'INVOICE_RELATED'=>'Invoices Related ', +'LBL_NOT_AVAILABLE'=>'Not available', +'LBL_EMAILID'=>'Email ID :', +'Created Time' =>'Created Time', +'Modified Time' =>'Modified Time', +'LBL_LANGUAGE'=>'Language', +'Related To' =>'Related To', +'MODULE_INACTIVE'=>'Module Inactive', + +// Tab names +'HelpDesk' =>'Tickets', +'Faq' =>'Knowledge Base', +'Accounts' =>'Account', +'Contacts' =>'Contacts', +'Products' =>'Products', +'Services' =>'Services', +'Quotes' =>'Quotes', +'Invoice' =>'Invoice', +'Documents' =>'Documents', +'HelpDesk' => 'Tickets', +'Faq' => 'Knowledge Base', +'Accounts' => 'Account', +'Contacts' => 'Contacts', +'Products' => 'Products', +'Services' => 'Services', +'Quotes' => 'Quotes', +'Invoice' => 'Invoice', +'Documents' => 'Documents', +'MORE_THAN_ONE_USER'=>'There may more than one user with this details. Please contact your administrator.', +'INVALID_USERNAME_OR_PASSWORD'=>'Invalid Username or Password', +'LBL_CATEGORY' => 'Category', +'Open'=>'Open', +'In Progress'=>'In Progress', +'Wait For Response'=>'Wait For Response', +'Closed'=>'Closed' , +'LBL_ANSWER'=>'ANSWER : ' + +); + + + + + + + +?> diff --git a/oss/vtiger/trunk/customerportal/login.php b/oss/vtiger/trunk/customerportal/login.php new file mode 100644 index 00000000..8e74d5fd --- /dev/null +++ b/oss/vtiger/trunk/customerportal/login.php @@ -0,0 +1,179 @@ + + + + + + +vtiger CRM 5 - CustomerPortal + + + + + + + + + + + + + + + + + + + + +



  
  + + + + + + + + + + + + + +
  
+ + + + + + + + + + + + + + + + +
  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
 
+
 
+ +
 
+ +
 
  
+ + + + + + + diff --git a/oss/vtiger/trunk/customerportal/nusoap/lib/nusoap.php b/oss/vtiger/trunk/customerportal/nusoap/lib/nusoap.php new file mode 100644 index 00000000..75e1638a --- /dev/null +++ b/oss/vtiger/trunk/customerportal/nusoap/lib/nusoap.php @@ -0,0 +1,5586 @@ + +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @access public +*/ +class nusoap_base { + + var $title = 'NuSOAP'; + var $version = '0.6.7'; + var $revision = '$Revision: 1.1 $'; + var $error_str = false; + var $debug_str = ''; + // toggles automatic encoding of special characters as entities + // (should always be true, I think) + var $charencoding = true; + + /** + * set schema version + * + * @var XMLSchemaVersion + * @access public + */ + var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + /** + * set charset encoding for outgoing messages + * + * @var soap_defencoding + * @access public + */ + //var $soap_defencoding = 'UTF-8'; + var $soap_defencoding = 'ISO-8859-1'; + + /** + * load namespace uris into an array of uri => prefix + * + * @var namespaces + * @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/', + 'si' => 'http://soapinterop.org/xsd'); + var $usedNamespaces = array(); + + /** + * load types into typemap array + * is this legacy yet? + * no, this is used by the xmlschema class to verify type => namespace mappings. + * @var typemap + * @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', + // 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/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') + ); + + /** + * entities to convert + * + * @var xmlEntities + * @access public + */ + var $xmlEntities = array('quot' => '"','amp' => '&', + 'lt' => '<','gt' => '>','apos' => "'"); + + /** + * 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"; + } + + /** + * 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 boolean $string error string + * @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 $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'. + * + * @return string + * @access public + */ + function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ + if(is_object($val) && get_class($val) == 'soapval'){ + return $val->serialize($use); + } + $this->debug( "in serialize_val: $val, $name, $type, $name_ns, $type_ns, $attributes, $use"); + // if no name, use item + $name = (!$name|| is_numeric($name)) ? 'soapVal' : $name; + // 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=\"$v\""; + } + } + // 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>$val"; + } else { + return "<$name$xmlns xsi:type=\"xsd:$type\">$val"; + } + } + // detect type and serialize + $xml = ''; + switch(true) { + case ($type == '' && is_null($val)): + if ($use == 'literal') { + // TODO: depends on nillable + $xml .= "<$name$xmlns/>"; + } else { + $xml .= "<$name$xmlns xsi:nil=\"true\"/>"; + } + break; + 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"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val"; + } + break; + case (is_int($val) || is_long($val) || $type == 'int'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val"; + } + break; + case (is_float($val)|| is_double($val) || $type == 'float'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val"; + } + break; + case (is_string($val) || $type == 'string'): + $val = $this->expandEntities($val); + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val"; + } + break; + case is_object($val): + $name = 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.''; + 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; + $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); + ++$i; + } + if(count($array_types) > 1){ + $array_typename = 'xsd:ur-type'; + } 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\""; + } + } + $xml = "<$name$xmlns$type_str$atts>".$xml.""; + } 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 .= ''; + $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); + $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); + $xml .= ''; + } else { + $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } + $xml .= ""; + } + break; + default: + $xml .= 'not detected, got '.gettype($val).' for '.$val; + break; + } + return $xml; + } + + /** + * serialize message + * + * @param string body + * @param string headers optional + * @param array namespaces optional + * @param string style optional (rpc|document) + * @param string use optional (encoded|literal) + * @return string message + * @access public + */ + function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded'){ + // 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 + + // serialize namespaces + $ns_string = ''; + foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ + $ns_string .= " xmlns:$k=\"$v\""; + } + if($style == 'rpc' && $use == 'encoded') { + $ns_string = ' SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"' . $ns_string; + } + + // serialize headers + if($headers){ + $headers = "".$headers.""; + } + // serialize envelope + return + 'soap_defencoding .'"?'.">". + '". + $headers. + "". + $body. + "". + ""; + } + + function formatDump($str){ + $str = htmlspecialchars($str); + return nl2br($str); + } + + /** + * contracts a qualified name + * + * @param string $string 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 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 + * @return string + * @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 + * @return mixed + * @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 + * returns false if no namespace registered with the given prefix + * + * @param string + * @return mixed + * @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 + * @return mixed + * @access public + */ + function getPrefixFromNamespace($ns) { + foreach ($this->namespaces as $p => $n) { + if ($ns == $n || $ns == $p) { + $this->usedNamespaces[$p] = $n; + return $p; + } + } + return false; + } + + function varDump($data) { + /* To avoid performance issue we skipping this */ + /*ob_start(); + var_dump($data); + $ret_val = ob_get_contents(); + ob_end_clean(); + return $ret_val;*/ + return ""; + } +} + +// 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; + } +} + +function usleepWindows($usec) +{ + $start = gettimeofday(); + + do + { + $stop = gettimeofday(); + $timePassed = 1000000 * ($stop['sec'] - $start['sec']) + + $stop['usec'] - $start['usec']; + } + while ($timePassed < $usec); +} + +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @access public +*/ +class soap_fault extends nusoap_base { + + var $faultcode; + var $faultactor; + var $faultstring; + 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 string $faultdetail + */ + function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ + $this->faultcode = $faultcode; + $this->faultactor = $faultactor; + $this->faultstring = $faultstring; + $this->faultdetail = $faultdetail; + } + + /** + * serialize a fault + * + * @access public + */ + function serialize(){ + $ns_string = ''; + foreach($this->namespaces as $k => $v){ + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + 'soap_defencoding.'"?>'. + '\n". + ''. + ''. + ''.$this->expandEntities($this->faultcode).''. + ''.$this->expandEntities($this->faultactor).''. + ''.$this->expandEntities($this->faultstring).''. + ''.$this->serialize_val($this->faultdetail).''. + ''. + ''. + ''; + return $return_msg; + } +} + + + +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @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 $currentComplexType = false; + var $elements = array(); + var $currentElement = false; + var $simpleTypes = array(); + var $currentSimpleType = false; + // 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()){ + + $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'){ + $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': + case 'choice': + 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': + //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); + $this->xdebug("parsing attribute " . $this->varDump($attrs)); + 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(isset($this->currentComplexType)){ + $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; + } elseif(isset($this->currentElement)){ + $this->elements[$this->currentElement]['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 'complexType': + 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'; + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $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'; + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + } + break; + case 'element': + // 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['type'])){ + $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + if (!isset($this->elements[ $attrs['name'] ]['form'])) { + $this->elements[ $attrs['name'] ]['form'] = $this->schemaInfo['elementFormDefault']; + } + $ename = $attrs['name']; + } elseif(isset($attrs['ref'])){ + $ename = $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'; + $this->elements[ $attrs['name'] ]['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; + if (!isset($this->elements[ $attrs['name'] ]['form'])) { + $this->elements[ $attrs['name'] ]['form'] = $this->schemaInfo['elementFormDefault']; + } + } + if(isset($ename) && $this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; + } + break; + // we ignore enumeration values + //case 'enumeration': + //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 'restriction': + //$this->xdebug("in restriction for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); + if($this->currentElement){ + $this->elements[$this->currentElement]['type'] = $attrs['base']; + } elseif($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'; + } + break; + case 'simpleType': + 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 { + //echo 'not parsing: '.$name; + //var_dump($attrs); + } + 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]; + } + // move on... + if($name == 'complexType'){ + $this->currentComplexType = false; + $this->currentElement = false; + } + if($name == 'element'){ + $this->currentElement = false; + } + if($name == 'simpleType'){ + $this->currentSimpleType = false; + } + } + + /** + * 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']) . "\"/>\n"; + } + } + } + // attributes + if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ + foreach($attrs['attrs'] as $attr => $aParts){ + $contentStr .= " <$schemaPrefix:attribute ref=\"".$this->contractQName($aParts['ref']).'"'; + if(isset($aParts['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ + $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; + $contentStr .= ' wsdl:arrayType="'.$this->contractQName($aParts['http://schemas.xmlsoap.org/wsdl/:arrayType']).'"'; + } + $contentStr .= "/>\n"; + } + } + // if restriction + if( isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ + $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." \n"; + } + // compositor obviates complex/simple content + if(isset($attrs['compositor']) && ($attrs['compositor'] != '')){ + $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." \n"; + } + // complex or simple content + elseif((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ + $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." \n"; + } + // finalize complex type + if($contentStr != ''){ + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." \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 => $attr){ + $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n contractQName($eParts['type'])."\"/>\n "; + } + } + // 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."\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 + */ + function getPHPType($type,$ns){ + if(isset($this->typemap[$ns][$type])){ + //print "found type '$type' and ns $ns in typemap
"; + return $this->typemap[$ns][$type]; + } elseif(isset($this->complexTypes[$type])){ + //print "getting type '$type' and ns $ns from complexTypes array
"; + return $this->complexTypes[$type]['phpType']; + } + return false; + } + + /** + * 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 string + * @return mixed + * @access public + */ + 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) { + 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) { + 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->elements[$type]['phpType'] = 'scalar'; + } + } + return $this->elements[$type]; + } elseif(isset($this->attributes[$type])){ + $this->xdebug("in getTypeDef, found attribute $type"); + return $this->attributes[$type]; + } + $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 + */ + function serializeTypeDef($type){ + //print "in sTD() for type $type
"; + 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 .= ""; + } elseif($typeDef['typeClass'] == 'element') { + $str .= ">"; + } 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 + */ + function typeToForm($name,$type){ + // get typedef + if($typeDef = $this->getTypeDef($type)){ + // if struct + if($typeDef['phpType'] == 'struct'){ + $buffer .= ''; + foreach($typeDef['elements'] as $child => $childDef){ + $buffer .= " + + "; + } + $buffer .= '
$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):
'; + // if array + } elseif($typeDef['phpType'] == 'array'){ + $buffer .= ''; + for($i=0;$i < 3; $i++){ + $buffer .= " + + "; + } + $buffer .= '
array item (type: $typeDef[arrayType]):
'; + // if scalar + } else { + $buffer .= ""; + } + } else { + $buffer .= ""; + } + 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) + * + */ + 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->varDump($this->complexTypes[$name])); + } + + /** + * adds a simple type to the schema + * + * @param name + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param typeClass (simpleType) + * @param phpType: (scalar) + * @see xmlschema + * + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar') { + $this->simpleTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'type' => $restrictionBase + ); + + $this->xdebug("addSimpleType $name: " . $this->varDump($this->simpleTypes[$name])); + } +} + + + +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @access public +*/ +class soapval extends nusoap_base { + /** + * constructor + * + * @param string $name optional name + * @param string $type optional type name + * @param mixed $value optional value + * @param string $namespace optional namespace of value + * @param string $type_namespace optional namespace of type + * @param array $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) { + $this->name = $name; + $this->value = $value; + $this->type = $type; + $this->element_ns = $element_ns; + $this->type_ns = $type_ns; + $this->attributes = $attributes; + } + + /** + * return serialized value + * + * @return string XML data + * @access private + */ + 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 + * + * @param object $soapval optional SOAPx4 soapval object, else uses self + * @return mixed + * @access public + */ + function decode(){ + return $this->value; + } +} + + + +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @access public +*/ +class soap_transport_http extends nusoap_base { + + var $url = ''; + var $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 $outgoing_payload = ''; + var $incoming_payload = ''; + var $useSOAPAction = true; + var $persistentConnection = false; + var $ch = false; // cURL handle + var $username; + var $password; + + /** + * constructor + */ + function soap_transport_http($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; + + // build headers + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; + if (!isset($u['port'])) { + $this->outgoing_headers['Host'] = $this->host; + } else { + $this->outgoing_headers['Host'] = $this->host.':'.$this->port; + } + + if (isset($u['user']) && $u['user'] != '') { + $this->setCredentials($u['user'], isset($u['pass']) ? $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); + + // 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 + 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); + // 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'; + } + // set timeout (NOTE: cURL does not have separate connection and response timeouts) + if ($connection_timeout != 0) { + curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_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); + + /* + TODO: support client certificates (thanks Tobias Boes) + curl_setopt($this->ch, CURLOPT_CAINFO, '$pathToPemFiles/rootca.pem'); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); + curl_setopt($this->ch, CURLOPT_SSLCERT, '$pathToPemFiles/mycert.pem'); + curl_setopt($this->ch, CURLOPT_SSLKEY, '$pathToPemFiles/mykey.pem'); + */ + $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 + * @return string data + * @access public + */ + function send($data, $timeout=0, $response_timeout=30) { + + $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)){ + 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 + * @return string data + * @access public + */ + function sendHTTPS($data, $timeout=0, $response_timeout=30) { + return $this->send($data, $timeout, $response_timeout); + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype + * @param array $digestRequest + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array()) { + global $_SERVER; + + $this->debug("Set credentials for authtype $authtype"); + // cf. RFC 2617 + if ($authtype == 'basic') { + $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode($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. ':' . $digestRequest['realm'] . ':' . $password; + + // H(A1) = MD5(A1) + $HA1 = md5($A1); + + // A2 = Method ":" digest-uri-value + $A2 = 'POST:' . $this->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->uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; + } + } + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->digestRequest = $digestRequest; + + if (isset($this->outgoing_headers['Authorization'])) { + $this->debug('Authorization header set: ' . 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 . '"'; + } + + /** + * use http encoding + * + * @param string $enc encoding style. supported values: gzip, deflate, or both + * @access public + */ + function setEncoding($enc='gzip, deflate'){ + $this->protocol_version = '1.1'; + $this->outgoing_headers['Accept-Encoding'] = $enc; + $this->outgoing_headers['Connection'] = 'close'; + $this->persistentConnection = false; + 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); + } + } + + /** + * 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 + */ + 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) { + // add content-length header + $this->outgoing_headers['Content-Length'] = strlen($data); + + // start building outgoing payload: + $this->outgoing_payload = "$this->request_method $this->uri HTTP/$this->protocol_version\r\n"; + + // loop thru headers, serializing + foreach($this->outgoing_headers as $k => $v){ + $this->outgoing_payload .= $k.': '.$v."\r\n"; + } + + // header/body separator + $this->outgoing_payload .= "\r\n"; + + // add data + $this->outgoing_payload .= $data; + } + + function sendRequest($data){ + // build payload + $this->buildPayload($data); + + 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"; + } + 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:\n" . $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(); + 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]); + } else if (isset($header_name)) { + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + + // loop until msg has been received + if (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; + if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { + $chunked = true; + $this->debug("want to read chunked content"); + } else { + $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 "
\nde-chunked:\n---------------\n$data\n\n---------------\n
"; + // 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.'
'; + foreach(curl_getinfo($this->ch) as $k => $v){ + $err .= "$k: $v
"; + } + $this->debug($err); + $this->setError($err); + curl_close($this->ch); + return false; + } else { + //echo '
';
+			//var_dump(curl_getinfo($this->ch));
+			//echo '
'; + } + // close curl + $this->debug('No cURL error, closing cURL'); + curl_close($this->ch); + + // remove 100 header + if (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) { + $this->incoming_headers[strtolower(trim($arr[0]))] = trim($arr[1]); + } + } + } + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['www-authenticate']) && strstr($header_array[0], '401 Unauthorized')) { + $this->debug('Got 401 Unauthorized with WWW-Authenticate: ' . $this->incoming_headers['www-authenticate']); + if (substr("Digest ", $this->incoming_headers['www-authenticate'])) { + $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)); + $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; + } + + // 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('gzuncompress')){ + //$timer->setMarker('starting decoding of gzip/deflated content'); + if($this->incoming_headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)){ + $data = $degzdata; + } elseif($this->incoming_headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))){ // do our best + $data = $degzdata; + } else { + $this->setError('Errors occurred when trying to decode the data'); + } + //$timer->setMarker('finished decoding of gzip/deflated content'); + //print "\nde-inflated:\n---------------\n$data\n-------------\n"; + // set decoded payload + $this->incoming_payload = $header_data.$lb.$lb.$data; + } else { + $this->setError('The server sent deflated data. Your php install must have the Zlib extension compiled in to support this.'); + } + } + } + + 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 : ''); + } + + 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'; + return true; + } +} + +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @access public +*/ +class soap_server extends nusoap_base { + var $headers = array(); // HTTP headers of request + var $request = ''; // HTTP request + var $requestHeaders = ''; // SOAP headers from request (incomplete namespace resolution) (text) + var $document = ''; // SOAP body request portion (incomplete namespace resolution) (text) + var $requestSOAP = ''; // SOAP payload for request (text) + var $methodURI = ''; // requested method namespace URI + var $methodname = ''; // name of method requested + var $methodparams = array(); // method parameters from request + var $xml_encoding = ''; // character set encoding of incoming (request) messages + var $SOAPAction = ''; // SOAP Action from request + + var $outgoing_headers = array();// HTTP headers of response + var $response = ''; // HTTP response + var $responseHeaders = ''; // SOAP headers for response (text) + var $responseSOAP = ''; // SOAP payload for response (text) + var $methodreturn = false; // method return to place in response + var $methodreturnisliteralxml = false; // whether $methodreturn is a string of literal XML + var $fault = false; // SOAP fault for response + var $result = 'successful'; // text indication of result (for debugging) + + var $operations = array(); // assoc array of operations => opData + var $wsdl = false; // wsdl instance + var $externalWSDLURL = false; // URL for WSDL + var $debug_flag = false; // whether to append debug to response as XML comment + + /** + * 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){ + + // turn on debugging? + global $debug; + global $_REQUEST; + global $_SERVER; + global $HTTP_SERVER_VARS; + + if (isset($debug)) { + $this->debug_flag = $debug; + } else if (isset($_REQUEST['debug'])) { + $this->debug_flag = $_REQUEST['debug']; + } else if (isset($_SERVER['QUERY_STRING'])) { + $qs = explode('&', $_SERVER['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug_flag = substr($v, 6); + } + } + } else if (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_flag = substr($v, 6); + } + } + } + + // wsdl + if($wsdl){ + if (is_object($wsdl) && is_a($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->debug("wsdl...\n" . $this->wsdl->debug_str); + $this->wsdl->debug_str = ''; + 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 $QUERY_STRING; + if(isset($_SERVER['QUERY_STRING'])){ + $qs = $_SERVER['QUERY_STRING']; + } elseif(isset($GLOBALS['QUERY_STRING'])){ + $qs = $GLOBALS['QUERY_STRING']; + } elseif(isset($QUERY_STRING) && $QUERY_STRING != ''){ + $qs = $QUERY_STRING; + } + + if(isset($qs) && ereg('wsdl', $qs) ){ + // 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); + } + } else { + header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); + print $this->wsdl->serialize(); + } + } elseif($data == '' && $this->wsdl){ + // print web interface + print $this->webDescription(); + } else { + // handle 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; + global $_SERVER; + + $this->request = ''; + if(function_exists('getallheaders')){ + $this->headers = getallheaders(); + foreach($this->headers as $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(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, but for XML, let's be pragmatic and admit UTF-8 is most common + $this->xml_encoding = 'UTF-8'; + } + } elseif(isset($_SERVER) && is_array($_SERVER)){ + foreach ($_SERVER as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($k, 5))))); + } else { + $k = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $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, but for XML, let's be pragmatic and admit UTF-8 is most common + $this->xml_encoding = 'UTF-8'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } elseif (is_array($HTTP_SERVER_VARS)) { + foreach ($HTTP_SERVER_VARS as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($k, 5))))); + 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, but for XML, let's be pragmatic and admit UTF-8 is most common + $this->xml_encoding = 'UTF-8'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } + } + } + + /** + * 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() on '.date('H:i Y-m-d')); + $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('Server', 'Errors occurred when trying to decode the data'); + return; + } + } else { + $this->fault('Server', 'This Server does not support compressed data'); + return; + } + } + } + $this->request .= "\r\n".$data; + $this->requestSOAP = $data; + // parse response, get soap parser obj + $parser = new soap_parser($data,$this->xml_encoding); + // parser debug + $this->debug("parser debug: \n".$parser->debug_str); + // if fault occurred during message parsing + if($err = $parser->getError()){ + $this->result = 'fault: error in msg parsing: '.$err; + $this->fault('Server',"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('method name: '.$this->methodname); + $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; + } + $this->debug('leaving parse_request() on '.date('H:i Y-m-d')); + } + + /** + * 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('entering invoke_method'); + // does method exist? + if(!function_exists($this->methodname)){ + // "method not found" fault here + $this->debug("method '$this->methodname' not found!"); + $this->result = 'fault: method not found'; + $this->fault('Server',"method '$this->methodname' not defined in service"); + return; + } + if($this->wsdl){ + if(!$this->opData = $this->wsdl->getOperationData($this->methodname)){ + //if( + $this->fault('Server',"Operation '$this->methodname' is not defined in the WSDL for this service"); + return; + } + $this->debug('opData is ' . $this->varDump($this->opData)); + } + $this->debug("method '$this->methodname' exists"); + // 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('Server',"Operation '$this->methodname' not defined in service."); + return; + } + + // if there are parameters to pass + $this->debug('params var dump '.$this->varDump($this->methodparams)); + if($this->methodparams){ + $this->debug("calling '$this->methodname' with params"); + if (! function_exists('call_user_func_array')) { + $this->debug('calling method using eval()'); + $funcCall = $this->methodname.'('; + foreach($this->methodparams as $param) { + $funcCall .= "\"$param\","; + } + $funcCall = substr($funcCall, 0, -1).')'; + $this->debug('function call:
'.$funcCall); + @eval("\$this->methodreturn = $funcCall;"); + } else { + $this->debug('calling method using call_user_func_array()'); + $this->methodreturn = call_user_func_array("$this->methodname",$this->methodparams); + } + } else { + // call method w/ no parameters + $this->debug("calling $this->methodname w/ no params"); + $m = $this->methodname; + $this->methodreturn = @$m(); + } + $this->debug('methodreturn var dump'.$this->varDump($this->methodreturn)); + $this->debug("leaving 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"); + // if we got nothing back. this might be ok (echoVoid) + if(isset($this->methodreturn) && ($this->methodreturn != '' || is_bool($this->methodreturn))) { + // if fault + if(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); + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->fault('Server', 'got wsdl error: '.$errstr); + return; + } + } else { + $return_val = $this->serialize_val($this->methodreturn, 'return'); + } + } + $this->debug('return val: '.$this->varDump($return_val)); + } else { + $return_val = ''; + $this->debug('got no response from method'); + } + $this->debug('serializing response'); + if ($this->wsdl) { + if ($this->opData['style'] == 'rpc') { + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } else { + $payload = $return_val; + } + } else { + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + $this->result = 'successful'; + if($this->wsdl){ + //if($this->debug_flag){ + $this->debug("WSDL debug data:\n".$this->wsdl->debug_str); + // } + // 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']); + } 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){ + while (strpos($this->debug_str, '--')) { + $this->debug_str = str_replace('--', '- -', $this->debug_str); + } + $payload .= ""; + } + $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"; + $this->outgoing_headers[] = "Content-Type: text/xml; charset=$this->soap_defencoding"; + //begin code to compress payload - by John + if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['Accept-Encoding'])) { + if (strstr($this->headers['Accept-Encoding'], 'deflate')) { + if (function_exists('gzcompress')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: deflate"; + $payload = gzcompress($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } else if (strstr($this->headers['Accept-Encoding'], 'gzip')) { + if (function_exists('gzencode')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: gzip"; + $payload = gzencode($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } + } + //end code + $this->outgoing_headers[] = "Content-Length: ".strlen($payload); + reset($this->outgoing_headers); + foreach($this->outgoing_headers as $hdr){ + header($hdr, false); + } + $this->response = join("\r\n",$this->outgoing_headers)."\r\n".$payload; + print $payload; + } + + /** + * takes the value that was created by parsing the request + * and compares to the method's signature, if available. + * + * @param mixed + * @return boolean + * @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; + } + + /** + * add a method to the dispatch map + * + * @param string $methodname + * @param string $in array of input values + * @param string $out array of output values + * @access public + */ + function add_to_map($methodname,$in,$out){ + $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); + } + + /** + * register a service with the server + * + * @param string $methodname + * @param string $in assoc array of input values: key = param name, value = param type + * @param string $out assoc array of output values: key = param name, value = param type + * @param string $namespace + * @param string $soapaction + * @param string $style optional (rpc|document) + * @param string $use optional (encoded|literal) + * @param string $documentation optional Description to include in WSDL + * @access public + */ + function register($name,$in=false,$out=false,$namespace=false,$soapaction=false,$style=false,$use=false,$documentation=''){ + 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(false == $in) { + } + if(false == $out) { + } + if(false == $namespace) { + } + if(false == $soapaction) { + $SERVER_NAME = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $GLOBALS['SERVER_NAME']; + $SCRIPT_NAME = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : $GLOBALS['SCRIPT_NAME']; + $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; + } + if(false == $style) { + $style = "rpc"; + } + if(false == $use) { + $use = "encoded"; + } + + $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); + } + return true; + } + + /** + * create a fault. 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=''){ + $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); + } + + /** + * prints html description of services + * + * @access private + */ + function webDescription(){ + $b = ' + NuSOAP: '.$this->wsdl->serviceName.' + + + + +
+

+
'.$this->wsdl->serviceName.'
+ +
'; + return $b; + } + + /** + * sets up wsdl object + * this acts as a flag to enable internal WSDL generation + * + * @param string $serviceName, name of the service + * @param string $namespace optional tns namespace + * @param string $endpoint optional URL of service endpoint + * @param string $style optional (rpc|document) WSDL style (also specified by operation) + * @param string $transport optional SOAP transport + * @param string $schemaTargetNamespace optional targetNamespace for service schema + */ + function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) + { + $SERVER_NAME = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $GLOBALS['SERVER_NAME']; + $SERVER_PORT = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $GLOBALS['SERVER_PORT']; + if ($SERVER_PORT == 80) { + $SERVER_PORT = ''; + } else { + $SERVER_PORT = ':' . $SERVER_PORT; + } + $SCRIPT_NAME = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : $GLOBALS['SCRIPT_NAME']; + if(false == $namespace) { + $namespace = "http://$SERVER_NAME/soap/$serviceName"; + } + + if(false == $endpoint) { + if (isset($_SERVER['HTTPS'])) { + $HTTPS = $_SERVER['HTTPS']; + } elseif (isset($GLOBALS['HTTPS'])) { + $HTTPS = $GLOBALS['HTTPS']; + } else { + $HTTPS = '0'; + } + 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/'); + } +} + + + +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @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){ + $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'] . + 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'] . + 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); + } + if (isset($wsdl_props['user'])) { + $tr->setCredentials($wsdl_props['user'],$wsdl_props['pass']); + } + $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->debug("transport debug data...\n" . $tr->debug_str); + // catch errors + if($err = $tr->getError() ){ + $errstr = 'HTTP ERROR: '.$err; + $this->debug($errstr); + $this->setError($errstr); + unset($tr); + return false; + } + unset($tr); + } 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; + } + } + // 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); + // 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->debug_str .= $this->currentSchema->debug_str; + $this->currentSchema->debug_str = ''; + } elseif (ereg('schema$', $name)) { + // $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->debug_str .= $this->currentSchema->debug_str; + $this->currentSchema->debug_str = ''; + } 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' => ''); + // get element prefix + 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); + } + + if (count($attrs) > 0) { + foreach($attrs as $k => $v) { + // if ns declarations, add to class level array of valid namespaces + 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') { + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v . '-instance'; + } + } // + // expand each attribute + $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(); + } + // 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->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->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; + } + 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) { + if ($operation == $bOperation) { + $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; + 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 + * @param $ns string + * @return mixed + * @access public + * @see xmlschema + */ + function getTypeDef($type, $ns) { + if ((! $ns) && isset($this->namespaces['tns'])) { + $ns = $this->namespaces['tns']; + } + if (isset($this->schemas[$ns])) { + foreach ($this->schemas[$ns] as $xs) { + $t = $xs->getTypeDef($type); + $this->debug_str .= $xs->debug_str; + $xs->debug_str = ''; + if ($t) { + return $t; + } + } + } + return false; + } + + /** + * serialize the parsed wsdl + * + * @return string , serialization of WSDL + * @access public + */ + function serialize() + { + $xml = '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 .= ''; + } else { + $xml .= ''; + } + } + } + } + // types + if (count($this->schemas)>=1) { + $xml .= ''; + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $xml .= $xs->serializeSchema(); + } + } + $xml .= ''; + } + // messages + if (count($this->messages) >= 1) { + foreach($this->messages as $msgName => $msgParts) { + $xml .= ''; + if(is_array($msgParts)){ + foreach($msgParts as $partName => $partType) { + // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'
'; + if (strpos($partType, ':')) { + $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); + } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { + // print 'checking typemap: '.$this->XMLSchemaVersion.'
'; + $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!"); + } + } + $xml .= ''; + } + } + $xml .= '
'; + } + } + // bindings & porttypes + if (count($this->bindings) >= 1) { + $binding_xml = ''; + $portType_xml = ''; + foreach($this->bindings as $bindingName => $attrs) { + $binding_xml .= ''; + $binding_xml .= ''; + $portType_xml .= ''; + foreach($attrs['operations'] as $opName => $opParts) { + $binding_xml .= ''; + $binding_xml .= ''; + if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + $binding_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $portType_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $binding_xml .= ''; + } + $xml .= $portType_xml . $binding_xml; + } + // services + $xml .= ''; + if (count($this->ports) >= 1) { + foreach($this->ports as $pName => $attrs) { + $xml .= ''; + $xml .= ''; + $xml .= ''; + } + } + $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 + */ + function serializeRPCParameters($operation, $direction, $parameters) + { + $this->debug('in serializeRPCParameters with operation '.$operation.', direction '.$direction.' and '.count($parameters).' param(s), and xml schema version ' . $this->XMLSchemaVersion); + + 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($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.'); + } + } + 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 + */ + function serializeParameters($operation, $direction, $parameters) + { + $this->debug('in serializeParameters with operation '.$operation.', direction '.$direction.' and '.count($parameters).' param(s), and xml schema version ' . $this->XMLSchemaVersion); + + 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($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.'); + } + } + return $xml; + } + + /** + * serializes a PHP value according a given type definition + * + * @param string $name , name of type (part) + * @param string $type , type of type, heh (type or element) + * @param mixed $value , a native PHP value (parameter value) + * @param string $use , use for part (encoded|literal) + * @param string $encodingStyle , use to add encoding changes to serialisation + * @return string serialization + * @access public + */ + function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false) + { + $this->debug("in serializeType: $name, $type, $value, $use, $encodingStyle"); + if($use == 'encoded' && $encodingStyle) { + $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; + } + + // if a soap_val has been supplied, let its type override the WSDL + if (is_object($value) && get_class($value) == 'soapval') { + // TODO: get attributes from soapval? + if ($value->type_ns) { + $type = $value->type_ns . ':' . $value->type; + } else { + $type = $value->type; + } + $value = $value->value; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type, value to $value"); + } else { + $forceType = false; + } + + $xml = ''; + if (strpos($type, ':')) { + $uqType = substr($type, strrpos($type, ':') + 1); + $ns = substr($type, 0, strrpos($type, ':')); + $this->debug("got a prefixed type: $uqType, $ns"); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + $this->debug("expanded prefixed type: $uqType, $ns"); + } + + if($ns == $this->XMLSchemaVersion){ + + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on nillable + return "<$name/>"; + } else { + return "<$name xsi:nil=\"true\"/>"; + } + } + if ($uqType == 'boolean' && !$value) { + $value = 'false'; + } elseif ($uqType == 'boolean') { + $value = 'true'; + } + if ($uqType == 'string' && gettype($value) == 'string') { + $value = $this->expandEntities($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) { + return "<$name xsi:type=\"" . $this->getPrefixFromNamespace($this->XMLSchemaVersion) . ":$uqType\">$value"; + } else { + return "<$name>$value"; + } + } else { + return "<$name xsi:type=\"" . $this->getPrefixFromNamespace($this->XMLSchemaVersion) . ":$uqType\"$encodingStyle>$value"; + } + } + } else if ($ns == 'http://xml.apache.org/xml-soap') { + if ($uqType == 'Map') { + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing map element: key $k, value $v"); + $contents .= ''; + $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); + $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); + $contents .= ''; + } + if ($use == 'literal') { + if ($forceType) { + return "<$name xsi:type=\"" . $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap') . ":$uqType\">$contents"; + } else { + return "<$name>$contents"; + } + } else { + return "<$name xsi:type=\"" . $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap') . ":$uqType\"$encodingStyle>$contents"; + } + } + } + } else { + $this->debug("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("$type ($uqType) is not a supported type."); + return false; + } else { + foreach($typeDef as $k => $v) { + $this->debug("typedef, $k: $v"); + } + } + $phpType = $typeDef['phpType']; + $this->debug("serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); + // if php type == struct, map value to the 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 { + $elementName = $name; + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on nillable + return "<$elementName$elementNS/>"; + } else { + return "<$elementName$elementNS xsi:nil=\"true\"/>"; + } + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$elementName$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; + } else { + $xml = "<$elementName$elementNS>"; + } + } else { + $xml = "<$elementName$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; + } + + if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { + 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 user took advantage of a minOccurs=0, then only serialize named parameters + if(isset($optionals) && !isset($xvalue[$eName])){ + // do nothing + } else { + // get value + if (isset($xvalue[$eName])) { + $v = $xvalue[$eName]; + } else { + $v = null; + } + // TODO: if maxOccurs > 1 (not just unbounded), then allow serialization of an array + if (isset($attrs['maxOccurs']) && $attrs['maxOccurs'] == 'unbounded' && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { + $vv = $v; + foreach ($vv as $k => $v) { + if (isset($attrs['type'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, $attrs['type'], $v, $use, $encodingStyle); + } else { + // serialize generic type + $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'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, $attrs['type'], $v, $use, $encodingStyle); + } else { + // serialize generic type + $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("Expected elements for XML Schema type $ns:$uqType"); + } + $xml .= ""; + } elseif ($phpType == 'array') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on nillable + return "<$name$elementNS/>"; + } else { + return "<$name$elementNS xsi:nil=\"true\"/>"; + } + } + 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); + } + } + $this->debug('contents: '.$this->varDump($contents)); + } 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 + .""; + } 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 + .""; + } + } elseif ($phpType == 'scalar') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = ''; + } + if ($use == 'literal') { + if ($forceType) { + return "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + return "<$name$elementNS>$value"; + } + } else { + return "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + } + $this->debug('returning: '.$this->varDump($xml)); + return $xml; + } + + /** + * adds an XML Schema complex type to the WSDL types + * + * @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) + * @see xmlschema + * + */ + 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 name + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param typeClass (simpleType) + * @param phpType: (scalar) + * @see xmlschema + * + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar') { + $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); + } + + /** + * register a service with the server + * + * @param string $methodname + * @param string $in assoc array of input values: key = param name, value = param type + * @param string $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 + * @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 + * @access public + */ + function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = ''){ + if ($style == 'rpc' && $use == 'encoded') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } else { + $encodingStyle = ''; + } + // 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; + } +} +?> +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @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 + * + * @param string $xml SOAP message + * @param string $encoding character encoding scheme of message + * @param string $method + * @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){ + $this->xml = $xml; + $this->xml_encoding = $encoding; + $this->method = $method; + $this->decode_utf8 = $decode_utf8; + + // Check whether content has been read. + if(!empty($xml)){ + $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]); + 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 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) { + // 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]; + } + } + // 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 string $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 complex 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); + } + + // set value of simple type + } else { + //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); + if (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 .= ""; + } + } elseif($pos >= $this->root_struct){ + $this->document .= ""; + } + // 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 string $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 entities + * + * @param string $text string to translate + * @access private + */ + function decode_entities($text){ + foreach($this->entities as $entity => $encoded){ + $text = str_replace($encoded,$entity,$text); + } + return $text; + } + + /** + * 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 + * @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') { + 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; + } + // everything else + return (string) $value; + } + + /** + * builds response structures for compound values (arrays/structs) + * + * @param string $pos position in node tree + * @access private + */ + function buildVal($pos){ + if(!isset($this->message[$pos]['type'])){ + $this->message[$pos]['type'] = ''; + } + $this->debug('inside buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); + // if there are children... + if($this->message[$pos]['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("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('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'){ + 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 + if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { + $notstruct = 1; + } else { + // is array or struct? + foreach($children as $child_pos){ + if(isset($keys) && isset($keys[$this->message[$child_pos]['name']])){ + $notstruct = 1; + break; + } + $keys[$this->message[$child_pos]['name']] = 1; + } + } + // + foreach($children as $child_pos){ + if(isset($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']])) { + $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']; + } + } + } + } + return is_array($params) ? $params : array(); + } else { + $this->debug('no children'); + if(strpos($this->message[$pos]['cdata'],'&')){ + return strtr($this->message[$pos]['cdata'],array_flip($this->entities)); + } else { + return $this->message[$pos]['cdata']; + } + } + } +} + + + +?>call( string methodname [ ,array parameters] ); +* +* // bye bye client +* unset($soapclient2); +* +* @author Dietrich Ayala +* @version $Id: nusoap.php,v 1.1 2005/04/29 05:09:16 sarajkumar Exp $ +* @access public +*/ +class soapclient2 extends nusoap_base { + + var $username = ''; + var $password = ''; + var $authtype = ''; + 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 $error_str = false; + 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 = ''; + 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 + // toggles whether the parser decodes element content w/ utf8_decode() + var $decode_utf8 = true; + + /** + * fault related variables + * + * @var fault + * @var faultcode + * @var faultstring + * @var faultdetail + * @access public + */ + var $fault, $faultcode, $faultstring, $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 soapclient2($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ + $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){ + $this->endpointType = 'wsdl'; + if (is_object($endpoint) && is_a($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->debug("wsdl debug...\n".$this->wsdl->debug_str); + $this->wsdl->debug_str = ''; + // 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); + } else { + $this->debug( 'getOperations returned false'); + $this->setError('no operations defined in the WSDL document!'); + } + } + } + + /** + * calls method, returns PHP native type + * + * @param string $method SOAP server URL or path + * @param array $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 boolean $headers optional array of soapval objects for 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 + * @access public + */ + function call($operation,$params=array(),$namespace='',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ + $this->operation = $operation; + $this->fault = false; + $this->error_str = ''; + $this->request = ''; + $this->response = ''; + $this->responseData = ''; + $this->faultstring = ''; + $this->faultcode = ''; + $this->opData = array(); + + $this->debug("call: $operation, $params, $namespace, $soapAction, $headers, $style, $use; endpointType: $this->endpointType"); + if ($headers) { + $this->requestHeaders = $headers; + } + // serialize parameters + if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ + // use WSDL for operation + $this->opData = $opData; + foreach($opData as $key => $value){ + $this->debug("$key -> $value"); + } + if (isset($opData['soapAction'])) { + $soapAction = $opData['soapAction']; + } + $this->endpoint = $opData['endpoint']; + $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : ($namespace != '' ? $namespace : 'http://testuri.org'); + $style = $opData['style']; + $use = $opData['input']['use']; + // add ns to ns array + if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ + $this->wsdl->namespaces['nu'] = $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; + // Partial fix for multiple encoding styles in the same function call + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if (isset($opData['output']['encodingStyle']) && $encodingStyle != $opData['output']['encodingStyle']) { + $methodEncodingStyle = ' SOAP-ENV:encodingStyle="' . $opData['output']['encodingStyle'] . '"'; + } else { + $methodEncodingStyle = ''; + } + $this->debug("wsdl debug: \n".$this->wsdl->debug_str); + $this->wsdl->debug_str = ''; + 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->setError( 'operation '.$operation.' not present.'); + $this->debug("operation '$operation' not present."); + $this->debug("wsdl debug: \n".$this->wsdl->debug_str); + $this->wsdl->debug_str = ''; + return false; + } else { + // no WSDL + if($namespace == ''){ + $namespace = 'http://testuri.org'; + } + //$this->namespaces['ns1'] = $namespace; + $nsPrefix = 'ns1'; + // 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(); + $methodEncodingStyle = ''; + } + // wrap RPC calls with method element + if ($style == 'rpc') { + if ($use == 'literal') { + $this->debug("wrapping RPC request with literal method element"); + $payload = "<$operation xmlns=\"$namespace\">" . $payload . ""; + } else { + $this->debug("wrapping RPC request with encoded method element"); + $payload = "<$nsPrefix:$operation$methodEncodingStyle xmlns:$nsPrefix=\"$namespace\">" . + $payload . + ""; + } + } + // serialize envelope + $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use); + $this->debug("endpoint: $this->endpoint, soapAction: $soapAction, namespace: $namespace, style: $style, use: $use"); + $this->debug('SOAP message length: ' . strlen($soapmsg) . ' contents: ' . 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).' back'); + + // 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
"); + } + return $return; + } else { + // array of return values + if(is_array($return)){ + // multiple 'out' parameters + if(sizeof($return) > 1){ + return $return; + } + // single 'out' parameter + return array_shift($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) { + // 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->username != '' && $this->password != '') { + $http->setCredentials($this->username, $this->password, $this->authtype); + } + 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); + } 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 + if (extension_loaded('curl')) { + $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout); + } else { + $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); + } + } else { + $this->setError('no http/s in endpoint url'); + } + $this->request = $http->outgoing_payload; + $this->response = $http->incoming_payload; + $this->debug("transport debug data...\n".$http->debug_str); + + // save transport object if using persistent connections + if ($this->persistentConnection) { + $http->debug_str = ''; + 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 protected + */ + 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, but for XML, let's be pragmatic and admit UTF-8 is most common + $this->xml_encoding = 'UTF-8'; + } + $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->debug($parser->debug_str); + // 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; + } + } + + /** + * set the SOAP headers + * + * @param $headers string XML + * @access public + */ + function setHeaders($headers){ + $this->requestHeaders = $headers; + } + + /** + * get the response headers + * + * @return mixed object SOAPx4 soapval object or empty if no headers + * @access public + */ + function getHeaders(){ + if($this->responseHeaders != '') { + 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) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic') { + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + } + + /** + * 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. + * + * @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. + * + * @param boolean $rpcParams + * @access public + */ + function setDefaultRpcParams($rpcParams) { + $this->defaultRpcParams = $rpcParams; + } + + /** + * dynamically creates proxy class, allowing user to directly call methods from wsdl + * + * @return object soap_proxy object + * @access public + */ + function getProxy(){ + $evalStr = ''; + foreach($this->operations as $operation => $opData){ + if($operation != ''){ + // create param string + $paramStr = ''; + if(sizeof($opData['input']['parts']) > 0){ + foreach($opData['input']['parts'] as $name => $type){ + $paramStr .= "\$$name,"; + } + $paramStr = substr($paramStr,0,strlen($paramStr)-1); + } + $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; + $evalStr .= "function $operation ($paramStr){ + // load params into array + \$params = array($paramStr); + return \$this->call('$operation',\$params,'".$opData['namespace']."','".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); + }"; + unset($paramStr); + } + } + $r = rand(); + $evalStr = 'class soap_proxy_'.$r.' extends soapclient2 { + '.$evalStr.' + }'; + //print "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->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; + return $proxy; + } + + /** + * 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 protected + */ + 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 protected + */ + 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 protected + */ + 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; + } +} +?> diff --git a/oss/vtiger/trunk/customerportal/supportpage.php b/oss/vtiger/trunk/customerportal/supportpage.php new file mode 100644 index 00000000..c986987d --- /dev/null +++ b/oss/vtiger/trunk/customerportal/supportpage.php @@ -0,0 +1,74 @@ +
'; + $list .= ''; + $list .= '
'; + $list .= ''; + $list .= ''; + $list .= ''; + $list .= ''; + $list .= ''; + if($mail_send_message != '') + { + $list .= ''; + } + $list .= ''; + $list .= ''; + $list .= ''; + $list .= '
'.getTranslatedString('LBL_FORGOT_LOGIN').'
 
'.$mail_send_message.'
'.getTranslatedString('LBL_YOUR_EMAIL').'
 
'; + + return $list; +} +if($_REQUEST['mail_send_message'] != '') +{ + $mail_send_message = explode("@@@",$_REQUEST['mail_send_message']); + + if($mail_send_message[0] == 'true') + { + $list = ''; + $list .= ''; + $list .= ''; + $list .= '
'; + $list .= ''; + $list .= '
'; + $list .= '
'; + $list .= getTranslatedString('LBL_FORGOT_LOGIN').'
 
'.$mail_send_message[1].'
 
'.getTranslatedString('LBL_CLOSE').''; + $list .= '
'; + + echo $list; + } + elseif($mail_send_message[0] == 'false') + { + $list = GetForgotPasswordUI($mail_send_message[1]); + echo $list; + } +} +elseif($_REQUEST['param'] == 'forgot_password') +{ + $list = GetForgotPasswordUI(); + echo $list; +} +elseif($_REQUEST['param'] == 'sign_up') +{ + echo 'Sign Up..........'; +} + + + + +?> diff --git a/oss/vtiger/trunk/customerportal/version.php b/oss/vtiger/trunk/customerportal/version.php new file mode 100644 index 00000000..72695683 --- /dev/null +++ b/oss/vtiger/trunk/customerportal/version.php @@ -0,0 +1,16 @@ +