Add php files

This commit is contained in:
2025-05-12 15:44:39 +00:00
parent c951760058
commit 82d5804ac4
9534 changed files with 2638137 additions and 0 deletions

15
soap/1.php Executable file
View File

@@ -0,0 +1,15 @@
<?php
$a = array("TEST", "@@@");
$x = base64_encode(serialize($a));
$x ="YTo0OntzOjEzOiJPcmRlci1TdW1tYXJ5IjthOjI6e3M6MTA6IlRvdGFsTGluZXMiO2k6MTtzOjE4OiJUb3RhbE9yZGVyZWRBbW91bnQiO2Q6MzAuNzM5OTk5OTk5OTk5OTk4NDM2ODA1OTgxMzI3Nzc5NTkxMDgzNTI2NjExMzI4MTI1O31zOjExOiJPcmRlci1MaW5lcyI7YToxOntpOjA7YToxOntzOjQ6IkxpbmUiO2E6MTp7czo5OiJMaW5lLUl0ZW0iO2E6MTI6e3M6MTA6IkxpbmVOdW1iZXIiO2k6MTtzOjQ6IkNPREUiO3M6MzY6IjYwZmFmOWM0LTM3ODQtNzZkMi1lZWM1LTRjZjhiYWUxMTM1OCI7czozOiJFQU4iO3M6MDoiIjtzOjEzOiJCdXllckl0ZW1Db2RlIjtzOjA6IiI7czoxNjoiU3VwcGxpZXJJdGVtQ29kZSI7czowOiIiO3M6MTU6Ikl0ZW1EZXNjcmlwdGlvbiI7czo0MToiRXR1aSBuYSBhcGFyYXQgY3lmcm93eSBQSE9UTyBDQVNFIChicm93bikiO3M6ODoiSXRlbVR5cGUiO3M6MjoiQ1UiO3M6MTU6Ik9yZGVyZWRRdWFudGl0eSI7czoxOiIxIjtzOjE5OiJPcmRlcmVkVW5pdFBhY2tzaXplIjtpOjE7czoxMzoiVW5pdE9mTWVhc3VyZSI7czozOiJQQ0UiO3M6MTk6Ik9yZGVyZWRVbml0TmV0UHJpY2UiO2Q6MzAuNzM5OTk5OTk5OTk5OTk4NDM2ODA1OTgxMzI3Nzc5NTkxMDgzNTI2NjExMzI4MTI1O3M6MTM6IlBhY2thZ2VOdW1iZXIiO3M6MDoiIjt9fX19czoxMzoiT3JkZXItUGFydGllcyI7YToxOntzOjU6IkJ1eWVyIjthOjM6e3M6NToiTG9naW4iO3M6MzY6IjYxZmIyYzI0LTBhMWQtYjQyZi01NTIzLTUyNjEwYTM3ZDM5ZiI7czoxMToiRGVzY3JpcHRpb24iO3M6MDoiIjtzOjE4OiJQYXltZW50Q29uZGl0aW9uSWQiO3M6MzY6IjIzZDE5YWE5LWQ2M2EtZGQ5OS01NjhjLTRkZmYwYmJjN2Y0MCI7fX1zOjEyOiJPcmRlci1IZWFkZXIiO2E6NDp7czo5OiJPcmRlckRhdGUiO3M6MTA6IjIwMTMtMTAtMTgiO3M6MjA6IkV4cGVjdGVkRGVsaXZlcnlEYXRlIjtzOjEwOiIyMDEzLTEwLTE4IjtzOjExOiJPcmRlck51bWJlciI7czo0OiJicmFrIjtzOjY6IlByZXN0YSI7czo5OiJTQ0RKQk5VSEQiO319";
echo "in = ".$x."<br><br>";
$y = unserialize(base64_decode($x));
echo "out = ".print_r($y)."<br><br>";
?>

324
soap/SoapData.php Executable file
View File

@@ -0,0 +1,324 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('soap/SoapRelationshipHelper.php');
set_time_limit(360);
$server->register(
'sync_get_modified_relationships',
array('session'=>'xsd:string', 'module_name'=>'xsd:string','related_module'=>'xsd:string', 'from_date'=>'xsd:string', 'to_date'=>'xsd:string','offset'=>'xsd:int', 'max_results'=>'xsd:int','deleted'=>'xsd:int', 'module_id'=>'xsd:string', 'select_fields'=>'tns:select_fields', 'ids'=>'tns:select_fields', 'relationship_name'=>'xsd:string', 'deletion_date'=>'xsd:string', 'php_serialize'=>'xsd:int'),
array('return'=>'tns:get_entry_list_result_encoded'),
$NAMESPACE);
/**
* Get a list of the relationship records that have been modified within a
* specified date range. This is used to perform a sync with a mobile client.
* The results are paged.
*
* @param xsd:string $session
* @param xsd:string $module_name
* @param xsd:string $related_module
* @param xsd:string $from_date
* @param xsd:string $to_date
* @param xsd:int $offset
* @param xsd:int $max_results
* @param xsd:int $deleted
* @param xsd:int $module_id
* @param tns:select_fields $select_fields
* @param tns:select_fields $ids
* @param xsd:string $relationship_name
* @param xsd:string $deletion_date
* @param xsd:int $php_serialize
* @return
*/
function sync_get_modified_relationships($session, $module_name, $related_module,$from_date,$to_date,$offset, $max_results, $deleted, $module_id = '', $select_fields = array(), $ids = array(), $relationship_name = '', $deletion_date = '', $php_serialize = 1){
global $beanList, $beanFiles;
$error = new SoapError();
$output_list = array();
if(!validate_authenticated($session)){
$error->set_error('invalid_login');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name]) || empty($beanList[$related_module])){
$error->set_error('no_module');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
global $current_user;
if(!check_modules_access($current_user, $module_name, 'read') || !check_modules_access($current_user, $related_module, 'read')){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($max_results > 0 || $max_results == '-99'){
global $sugar_config;
$sugar_config['list_max_entries_per_page'] = $max_results;
}
$date_query = "(m1.date_modified > " . db_convert("'$from_date'", 'datetime'). " AND m1.date_modified <= ". db_convert("'$to_date'", 'datetime')." AND {0}.deleted = $deleted)";
if(isset($deletion_date) && !empty($deletion_date)){
$date_query .= " OR ({0}.date_modified > " . db_convert("'$deletion_date'", 'datetime'). " AND {0}.date_modified <= ". db_convert("'$to_date'", 'datetime')." AND {0}.deleted = 1)";
}
$in = '';
if(isset($ids) && !empty($ids)){
foreach($ids as $value){
if(empty($in))
{
$in .= "('" . $value . "'";
}
else
{
$in .= ",'" . $value . "'";
}
}
$in .=')';
}
$query = '';
if(isset($in) && !empty($in)){
$query .= "( $date_query AND m1.id IN $in) OR (m1.id NOT IN $in AND {0}.deleted = 0)";
}
else{
$query .= "( {0}.deleted = 0)";
}
if(isset($module_id) && !empty($module_id)){
//if(isset($in) && !empty($in)){
$query .= " AND";
//}
$query .= " m2.id = '$module_id'";
}
if($related_module == 'Meetings' || $related_module == 'Calls'){
$query = string_format($query, array('m1'));
}
$results = retrieve_modified_relationships($module_name, $related_module, $query, $deleted, $offset, $max_results, $select_fields, $relationship_name);
$list = $results['result'];
$xml = '<?xml version="1.0" encoding="utf-8"?><items>';
foreach($list as $value)
{
$val = array_get_return_value($value, $results['table_name']);
if($php_serialize == 0){
$xml .= get_name_value_xml($val, $module_name);
}
$output_list[] = $val;
}
$xml .= '</items>';
$next_offset = $offset + sizeof($output_list);
if($php_serialize == 0){
$myoutput = base64_encode($xml);
}
else{
$myoutput = get_encoded($output_list);
}
return array('result_count'=>sizeof($output_list),'next_offset'=>0, 'total_count'=>sizeof($output_list), 'field_list'=>array(), 'entry_list'=>$myoutput , 'error'=>$error->get_soap_array());
}
$server->register(
'get_modified_entries',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'ids'=>'tns:select_fields', 'select_fields'=>'tns:select_fields'),
array('return'=>'tns:get_sync_result_encoded'),
$NAMESPACE);
function get_modified_entries($session, $module_name, $ids, $select_fields ){
global $beanList, $beanFiles;
$error = new SoapError();
$field_list = array();
$output_list = array();
if(!validate_authenticated($session)){
$error->set_error('invalid_login');
return array('field_list'=>$field_list, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('field_list'=>$field_list, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
global $current_user;
if(!check_modules_access($current_user, $module_name, 'read')){
$error->set_error('no_access');
return array('field_list'=>$field_list, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
//rsmith
$in = '';
$field_select ='';
$table_name = $seed->table_name;
if(isset($ids)){
foreach($ids as $value){
if(empty($in))
{
$in .= "('" . $value . "'";
}
else
{
$in .= ",'" . $value . "'";
}
}//end foreach
}
$index = 0;
foreach($select_fields as $field){
$field_select .= $table_name.".".$field;
if($index < (count($select_fields) - 1))
{
$field_select .= ",";
$index++;
}
}//end foreach
$ids = array();
//end rsmith
if(!empty($in)){
$in .=')';
}
$ret_array = $seed->create_new_list_query('', "$table_name.id IN $in", $select_fields, array(), -2, '', true, $seed, true);
if(!is_array($params)) $params = array();
if(!isset($params['custom_select'])) $params['custom_select'] = '';
if(!isset($params['custom_from'])) $params['custom_from'] = '';
if(!isset($params['custom_where'])) $params['custom_where'] = '';
if(!isset($params['custom_order_by'])) $params['custom_order_by'] = '';
$main_query = $ret_array['select'] . $params['custom_select'] . $ret_array['from'] . $params['custom_from'] . $ret_array['where'] . $params['custom_where'] . $ret_array['order_by'] . $params['custom_order_by'];
$result = $seed->db->query($main_query);
$xml = '<?xml version="1.0" encoding="utf-8"?><items>';
while($row = $seed->db->fetchByAssoc($result))
{
if (version_compare(phpversion(), '5.0') < 0) {
$temp = $seed;
} else {
$temp = @clone($seed);
}
$temp->setupCustomFields($temp->module_dir);
$temp->loadFromRow($row);
$temp->fill_in_additional_detail_fields();
if(isset($temp->emailAddress)){
$temp->emailAddress->handleLegacyRetrieve($temp);
}
$val = get_return_value($temp, $table_name);
$xml .= get_name_value_xml($val, $module_name);
}
$xml .= "</items>";
$xml = base64_encode($xml);
return array('result'=>$xml, 'error'=>$error->get_soap_array());
}
$server->register(
'get_attendee_list',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'id'=>'xsd:string'),
array('return'=>'tns:get_sync_result_encoded'),
$NAMESPACE);
function get_attendee_list($session, $module_name, $id){
global $beanList, $beanFiles;
$error = new SoapError();
$field_list = array();
$output_list = array();
if(!validate_authenticated($session)){
$error->set_error('invalid_login');
return array('field_list'=>$field_list, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('field_list'=>$field_list, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
global $current_user;
if(!check_modules_access($current_user, $module_name, 'read')){
$error->set_error('no_access');
return array('field_list'=>$field_list, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
require_once('modules/Users/User.php');
require_once('modules/Contacts/Contact.php');
//rsmith
$xml = '<?xml version="1.0" encoding="utf-8"?>';
if($module_name == 'Meetings' || $module_name == 'Calls'){
//if we find a meeting or call we want to send back the attendees
$l_module_name = strtolower($module_name);
$table_name = $l_module_name."_users";
if($module_name == 'Meetings')
$join_field = "meeting";
else
$join_field = "call";
$xml .= '<attendees>';
$result = $seed->db->query("SELECT users.id, $table_name.date_modified, first_name, last_name FROM users INNER JOIN $table_name ON $table_name.user_id = users.id WHERE ".$table_name.".".$join_field."_id = '".$id."' AND $table_name.deleted = 0");
$user = new User();
while($row = $seed->db->fetchByAssoc($result))
{
$user->id = $row['id'];
$email = $user->emailAddress->getPrimaryAddress($user);
$xml .= '<attendee>';
$xml .= '<id>'.$user->id.'</id>';
$xml .= '<first_name>'.$row['first_name'].'</first_name>';
$xml .= '<last_name>'.$row['last_name'].'</last_name>';
$xml .= '<email1>'.$email.'</email1>';
$xml .= '</attendee>';
}
//now get contacts
$table_name = $l_module_name."_contacts";
$result = $seed->db->query("SELECT contacts.id, $table_name.date_modified, first_name, last_name FROM contacts INNER JOIN $table_name ON $table_name.contact_id = contacts.id INNER JOIN $seed->table_name ON ".$seed->table_name.".id = ".$table_name.".".$join_field."_id WHERE ".$table_name.".".$join_field."_id = '".$id."' AND ".$table_name.".deleted = 0 AND (contacts.id != ".$seed->table_name.".parent_id OR ".$seed->table_name.".parent_id IS NULL)");
$contact = new Contact();
while($row = $seed->db->fetchByAssoc($result))
{
$contact->id = $row['id'];
$email = $contact->emailAddress->getPrimaryAddress($contact);
$xml .= '<attendee>';
$xml .= '<id>'.$contact->id.'</id>';
$xml .= '<first_name>'.$row['first_name'].'</first_name>';
$xml .= '<last_name>'.$row['last_name'].'</last_name>';
$xml .= '<email1>'.$email.'</email1>';
$xml .= '</attendee>';
}
$xml .= '</attendees>';
}
$xml = base64_encode($xml);
return array('result'=>$xml, 'error'=>$error->get_soap_array());
}
?>

2401
soap/SoapDeprecated.php Executable file

File diff suppressed because it is too large Load Diff

1483
soap/SoapDeprecated1.php Executable file

File diff suppressed because it is too large Load Diff

2400
soap/SoapDeprecated2.php Executable file

File diff suppressed because it is too large Load Diff

72
soap/SoapError.php Executable file
View File

@@ -0,0 +1,72 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('soap/SoapErrorDefinitions.php');
class SoapError{
var $name;
var $number;
var $description;
function SoapError(){
$this->set_error('no_error');
}
function set_error($error_name){
global $error_defs;
if(!isset($error_defs[$error_name])){
$this->name = 'An Undefined Error - ' . $error_name . ' occured';
$this->number = '-1';
$this->description = 'There is no error definition for ' . $error_name;
}else{
$this->name = $error_defs[$error_name]['name'];
$this->number = $error_defs[$error_name]['number'];
$this->description = $error_defs[$error_name]['description'];
}
}
function get_soap_array(){
return Array('number'=>$this->number,
'name'=>$this->name,
'description'=>$this->description);
}
}
?>

68
soap/SoapErrorDefinitions.php Executable file
View File

@@ -0,0 +1,68 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
$error_defs = array(
'no_error'=>array('number'=>0 , 'name'=>'No Error', 'description'=>'No Error'),
'invalid_login'=>array('number'=>10 , 'name'=>'Invalid Login', 'description'=>'Login attempt failed please check the username and password'),
'invalid_session'=>array('number'=>11 , 'name'=>'Invalid Session ID', 'description'=>'The session ID is invalid'),
'user_not_configure'=>array('number'=>12 , 'name'=>'User Not Configured', 'description'=>'Please log into your instance of SugarCRM to configure your user. '),
'no_portal'=>array('number'=>12 , 'name'=>'Invalid Portal Client', 'description'=>'Portal Client does not have authorized access'),
'no_module'=>array('number'=>20 , 'name'=>'Module Does Not Exist', 'description'=>'This module is not available on this server'),
'no_file'=>array('number'=>21 , 'name'=>'File Does Not Exist', 'description'=>'The desired file does not exist on the server'),
'no_module_support'=>array('number'=>30 , 'name'=>'Module Not Supported', 'description'=>'This module does not support this feature'),
'no_relationship_support'=>array('number'=>31 , 'name'=>'Relationship Not Supported', 'description'=>'This module does not support this relationship'),
'no_access'=>array('number'=>40 , 'name'=>'Access Denied', 'description'=>'You do not have access'),
'duplicates'=>array('number'=>50 , 'name'=>'Duplicate Records', 'description'=>'Duplicate records have been found. Please be more specific.'),
'no_records'=>array('number'=>51 , 'name'=>'No Records', 'description'=>'No records were found.'),
'cannot_add_client'=>array('number'=>52 , 'name'=>'Cannot Add Offline Client', 'description'=>'Unable to add Offline Client.'),
'client_deactivated'=>array('number'=>53 , 'name'=>'Client Deactivated', 'description'=>'Your Offline Client instance has been deactivated. Please contact your Administrator in order to resolve.'),
'sessions_exceeded'=>array('number'=>60 , 'name'=>'Number of sessions exceeded.'),
'upgrade_client'=>array('number'=>61 , 'name'=>'Upgrade Client', 'description'=>'Please contact your Administrator in order to upgrade your Offline Client'),
'no_admin' => array('number' => 70, 'name' => 'Admin credentials are required', 'description' => 'The logged-in user is not an administrator'),
'custom_field_type_not_supported' => array('number' => 80, 'name' => 'Custom field type not supported', 'description' => 'The custom field type you supplied is not currently supported'),
'custom_field_property_not_supplied' => array('number' => 81, 'name' => 'Custom field property not supplied', 'description' => 'You are missing one or more properties for the supplied custom field type'),
'resource_management_error' => array('number'=>90, 'name'=>'Resource Management Error', 'description'=>'The resource query limit specified in config.php has been exceeded during execution of the SOAP method'),
);
?>

723
soap/SoapHelperFunctions.php Executable file
View File

@@ -0,0 +1,723 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
/**
* Retrieve field data for a provided SugarBean.
*
* @param SugarBean $value -- The bean to retrieve the field information for.
* @return Array -- 'field'=> 'name' -- the name of the field
* 'type' -- the data type of the field
* 'label' -- the translation key for the label of the field
* 'required' -- Is the field required?
* 'options' -- Possible values for a drop down field
*/
function get_field_list(&$value, $translate=true){
$list = array();
if(!empty($value->field_defs)){
foreach($value->field_defs as $var){
if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate'))continue;
$required = 0;
$options_dom = array();
$options_ret = array();
// Apparently the only purpose of this check is to make sure we only return fields
// when we've read a record. Otherwise this function is identical to get_module_field_list
if(isset($value->required_fields) && key_exists($var['name'], $value->required_fields)){
$required = 1;
}
if(isset($var['options'])){
$options_dom = translate($var['options'], $value->module_dir);
if(!is_array($options_dom)) $options_dom = array();
foreach($options_dom as $key=>$oneOption)
$options_ret[] = get_name_value($key,$oneOption);
}
if(!empty($var['dbType']) && $var['type'] == 'bool') {
$options_ret[] = get_name_value('type', $var['dbType']);
}
$entry = array();
$entry['name'] = $var['name'];
$entry['type'] = $var['type'];
if($translate) {
$entry['label'] = isset($var['vname']) ? translate($var['vname'], $value->module_dir) : $var['name'];
} else {
$entry['label'] = isset($var['vname']) ? $var['vname'] : $var['name'];
}
$entry['required'] = $required;
$entry['options'] = $options_ret;
if(isset($var['default'])) {
$entry['default_value'] = $var['default'];
}
$list[$var['name']] = $entry;
} //foreach
} //if
if($value->module_dir == 'Bugs'){
require_once('modules/Releases/Release.php');
$seedRelease = new Release();
$options = $seedRelease->get_releases(TRUE, "Active");
$options_ret = array();
foreach($options as $name=>$value){
$options_ret[] = array('name'=> $name , 'value'=>$value);
}
if(isset($list['fixed_in_release'])){
$list['fixed_in_release']['type'] = 'enum';
$list['fixed_in_release']['options'] = $options_ret;
}
if(isset($list['release'])){
$list['release']['type'] = 'enum';
$list['release']['options'] = $options_ret;
}
if(isset($list['release_name'])){
$list['release_name']['type'] = 'enum';
$list['release_name']['options'] = $options_ret;
}
}
if(isset($value->assigned_user_name) && isset($list['assigned_user_id'])) {
$list['assigned_user_name'] = $list['assigned_user_id'];
$list['assigned_user_name']['name'] = 'assigned_user_name';
}
if(isset($list['modified_user_id'])) {
$list['modified_by_name'] = $list['modified_user_id'];
$list['modified_by_name']['name'] = 'modified_by_name';
}
if(isset($list['created_by'])) {
$list['created_by_name'] = $list['created_by'];
$list['created_by_name']['name'] = 'created_by_name';
}
return $list;
}
function get_name_value($field,$value){
return array('name'=>$field, 'value'=>$value);
}
function get_user_module_list($user){
global $app_list_strings, $current_language;
$app_list_strings = return_app_list_strings_language($current_language);
$modules = query_module_access_list($user);
ACLController :: filterModuleList($modules, false);
global $modInvisList, $modInvisListActivities;
foreach($modInvisList as $invis){
$modules[$invis] = 'read_only';
}
if(isset($modules['Calendar']) || $modules['Activities']){
foreach($modInvisListActivities as $invis){
$modules[$invis] = $invis;
}
}
return $modules;
}
function check_modules_access($user, $module_name, $action='write'){
if(!isset($_SESSION['avail_modules'])){
$_SESSION['avail_modules'] = get_user_module_list($user);
}
if(isset($_SESSION['avail_modules'][$module_name])){
if($action == 'write' && $_SESSION['avail_modules'][$module_name] == 'read_only'){
if(is_admin($user))return true;
return false;
}
return true;
}
return false;
}
function get_name_value_list(&$value){
global $app_list_strings;
$list = array();
if(!empty($value->field_defs)){
if(isset($value->assigned_user_name)) {
$list['assigned_user_name'] = get_name_value('assigned_user_name', $value->assigned_user_name);
}
if(isset($value->modified_by_name)) {
$list['modified_by_name'] = get_name_value('modified_by_name', $value->modified_by_name);
}
if(isset($value->created_by_name)) {
$list['created_by_name'] = get_name_value('created_by_name', $value->created_by_name);
}
foreach($value->field_defs as $var){
if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate'))continue;
if(isset($value->$var['name'])){
$val = $value->$var['name'];
$type = $var['type'];
if(strcmp($type, 'date') == 0){
$val = substr($val, 0, 10);
}elseif(strcmp($type, 'enum') == 0 && !empty($var['options'])){
$val = $app_list_strings[$var['options']][$val];
}
$list[$var['name']] = get_name_value($var['name'], $val);
}
}
}
return $list;
}
function array_get_name_value_list($array){
$list = array();
foreach($array as $name=>$value){
$list[$name] = get_name_value($name, $value);
}
return $list;
}
function array_get_name_value_lists($array){
$list = array();
foreach($array as $name=>$value){
$tmp_value=$value;
if(is_array($value)){
$tmp_value = array();
foreach($value as $k=>$v){
$tmp_value[] = get_name_value($k, $v);
}
}
$list[] = get_name_value($name, $tmp_value);
}
return $list;
}
function name_value_lists_get_array($list){
$array = array();
foreach($list as $key=>$value){
if(isset($value['value']) && isset($value['name'])){
if(is_array($value['value'])){
$array[$value['name']]=array();
foreach($value['value'] as $v){
$array[$value['name']][$v['name']]=$v['value'];
}
}else{
$array[$value['name']]=$value['value'];
}
}
}
return $array;
}
function array_get_return_value($array, $module){
return Array('id'=>$array['id'],
'module_name'=> $module,
'name_value_list'=>array_get_name_value_list($array)
);
}
function get_return_value(&$value, $module){
global $module_name, $current_user;
$module_name = $module;
if($module == 'Users' && $value->id != $current_user->id){
$value->user_hash = '';
}
return Array('id'=>$value->id,
'module_name'=> $module,
'name_value_list'=>get_name_value_list($value)
);
}
function get_name_value_xml($val, $module_name){
$xml = '<item>';
$xml .= '<id>'.$val['id'].'</id>';
$xml .= '<module>'.$module_name.'</module>';
$xml .= '<name_value_list>';
foreach($val['name_value_list'] as $name=>$nv){
$xml .= '<name_value>';
$xml .= '<name>'.htmlspecialchars($nv['name']).'</name>';
$xml .= '<value>'.htmlspecialchars($nv['value']).'</value>';
$xml .= '</name_value>';
}
$xml .= '</name_value_list>';
$xml .= '</item>';
return $xml;
}
/*
function get_module_field_list(&$value){
$list = array();
if(!empty($value->field_defs)){
foreach($value->field_defs as $var){
$required = 0;
$options_dom = array();
$translateOptions = false;
if(isset($value->required_fields) && key_exists($var['name'], $value->required_fields)){
$required = 1;
}
if(isset($var['options'])){
$options_dom = $var['options'];
$translateOptions = true;
}
if($value->module_dir == 'Bugs'){
require_once('modules/Releases/Release.php');
$seedRelease = new Release();
$options = $seedRelease->get_releases(TRUE, "Active");
if($var['name'] == 'fixed_in_release'){
$var['type'] = 'enum';
$translateOptions = false;
foreach($options as $name=>$avalue){
$options_dom[$avalue] = $name;
}
}
if($var['name'] == 'release'){
$var['type'] = 'enum';
$translateOptions = false;
foreach($options as $name=>$avalue){
$options_dom[$avalue] = $name;
}
}
}
$list[$var['name']] = array('name'=>$var['name'],
'type'=>$var['type'],
'label'=>translate($var['vname'], $value->module_dir),
'required'=>$required,
'options'=>get_field_options($options_dom, $translateOptions) );
}
}
return $list;
}
*/
function get_return_module_fields(&$value, $module, &$error, $translate=true){
global $module_name;
$module_name = $module;
return Array('module_name'=>$module,
'module_fields'=> get_field_list($value, $translate),
'error'=>get_name_value_list($value)
);
}
function get_return_error_value($error_num, $error_name, $error_description){
return Array('number'=>$error_num,
'name'=> $error_name,
'description'=> $error_description
);
}
function filter_field_list(&$field_list, &$select_fields, $module_name){
return filter_return_list($field_list, $select_fields, $module_name);
}
/**
* Filter the results of a list query. Limit the fields returned.
*
* @param Array $output_list -- The array of list data
* @param Array $select_fields -- The list of fields that should be returned. If this array is specfied, only the fields in the array will be returned.
* @param String $module_name -- The name of the module this being worked on
* @return The filtered array of list data.
*/
function filter_return_list(&$output_list, $select_fields, $module_name){
for($sug = 0; $sug < sizeof($output_list) ; $sug++){
if($module_name == 'Contacts'){
global $invalid_contact_fields;
if(is_array($invalid_contact_fields)){
foreach($invalid_contact_fields as $name=>$val){
unset($output_list[$sug]['field_list'][$name]);
unset($output_list[$sug]['name_value_list'][$name]);
}
}
}
if( !empty($output_list[$sug]['name_value_list']) && is_array($output_list[$sug]['name_value_list']) && !empty($select_fields) && is_array($select_fields)){
foreach($output_list[$sug]['name_value_list'] as $name=>$value)
if(!in_array($value['name'], $select_fields)){
unset($output_list[$sug]['name_value_list'][$name]);
unset($output_list[$sug]['field_list'][$name]);
}
}
}
return $output_list;
}
function login_success(){
global $current_language, $sugar_config, $app_strings, $app_list_strings;
$current_language = $sugar_config['default_language'];
$app_strings = return_application_language($current_language);
$app_list_strings = return_app_list_strings_language($current_language);
}
/*
* Given an account_name, either create the account or assign to a contact.
*/
function add_create_account(&$seed)
{
global $current_user;
$account_name = $seed->account_name;
$account_id = $seed->account_id;
$assigned_user_id = $current_user->id;
// check if it already exists
$focus = new Account();
if( $focus->ACLAccess('Save')){
$class = get_class($seed);
$temp = new $class();
$temp->retrieve($seed->id);
if ((! isset($account_name) || $account_name == ''))
{
return;
}
if (!isset($seed->accounts)){
$seed->load_relationship('accounts');
}
if($seed->account_name = '' && isset($temp->account_id)){
$seed->accounts->delete($seed->id, $temp->account_id);
return;
}
$arr = array();
$query = "select id, deleted from {$focus->table_name} WHERE name='".$seed->db->quote($account_name)."'";
$result = $seed->db->query($query) or sugar_die("Error selecting sugarbean: ".mysql_error());
$row = $seed->db->fetchByAssoc($result, -1, false);
// we found a row with that id
if (isset($row['id']) && $row['id'] != -1)
{
// if it exists but was deleted, just remove it entirely
if ( isset($row['deleted']) && $row['deleted'] == 1)
{
$query2 = "delete from {$focus->table_name} WHERE id='". $seed->db->quote($row['id'])."'";
$result2 = $seed->db->query($query2) or sugar_die("Error deleting existing sugarbean: ".mysql_error());
}
// else just use this id to link the contact to the account
else
{
$focus->id = $row['id'];
}
}
// if we didnt find the account, so create it
if (! isset($focus->id) || $focus->id == '')
{
$focus->name = $account_name;
if ( isset($assigned_user_id))
{
$focus->assigned_user_id = $assigned_user_id;
$focus->modified_user_id = $assigned_user_id;
}
$focus->save();
}
if($seed->accounts != null && $temp->account_id != null && $temp->account_id != $focus->id){
$seed->accounts->delete($seed->id, $temp->account_id);
}
if(isset($focus->id) && $focus->id != ''){
$seed->account_id = $focus->id;
}
}
}
function check_for_duplicate_contacts(&$seed){
require_once('modules/Contacts/Contact.php');
if(isset($seed->id)){
return null;
}
$query = '';
$trimmed_email = trim($seed->email1);
$trimmed_last = trim($seed->last_name);
$trimmed_first = trim($seed->first_name);
if(!empty($trimmed_email)){
//obtain a list of contacts which contain the same email address
$contacts = $seed->emailAddress->getBeansByEmailAddress($trimmed_email);
if(count($contacts) == 0){
return null;
}else{
foreach($contacts as $contact){
if(!empty($trimmed_last) && strcmp($trimmed_last, $contact->last_name) == 0){
if(!empty($trimmed_email) && strcmp($trimmed_email, $contact->email1) == 0){
if(!empty($trimmed_email)){
if(strcmp($trimmed_email, $contact->email1) == 0)
return $contact->id;
}else
return $contact->id;
}
}
}
return null;
}
}else{
$query = "contacts.last_name = '$trimmed_last'";
$query .= " AND contacts.first_name = '$trimmed_first'";
$contacts = $seed->get_list('', $query);
if (count($contacts) == 0){
return null;
}else{
foreach($contacts['list'] as $contact){
if (empty($contact->email1)){
return $contact->id;
}
}
return null;
}
}
}
/*
* Given a client version and a server version, determine if the right hand side(server version) is greater
*
* @param left the client sugar version
* @param right the server version
*
* return true if the server version is greater or they are equal
* false if the client version is greater
*/
function is_server_version_greater($left, $right){
if(count($left) == 0 && count($right) == 0){
return false;
}
else if(count($left) == 0 || count($right) == 0){
return true;
}
else if($left[0] == $right[0]){
array_shift($left);
array_shift($right);
return is_server_version_greater($left, $right);
}
else if($left[0] < $right[0]){
return true;
}
else
return false;
}
function getFile( $zip_file, $file_in_zip ){
global $sugar_config;
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
$my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
return( "$my_zip_dir/$file_in_zip" );
}
function getManifest( $zip_file ){
ini_set("max_execution_time", "3600");
return( getFile( $zip_file, "manifest.php" ) );
}
/**
* Use the same logic as in SugarAuthenticate to validate the ip address
*
* @param string $session_var
* @return bool - true if the ip address is valid, false otherwise.
*/
function is_valid_ip_address($session_var){
global $sugar_config;
// grab client ip address
$clientIP = query_client_ip();
$classCheck = 0;
// check to see if config entry is present, if not, verify client ip
if (!isset ($sugar_config['verify_client_ip']) || $sugar_config['verify_client_ip'] == true) {
// check to see if we've got a current ip address in $_SESSION
// and check to see if the session has been hijacked by a foreign ip
if (isset ($_SESSION[$session_var])) {
$session_parts = explode(".", $_SESSION[$session_var]);
$client_parts = explode(".", $clientIP);
if(count($session_parts) < 4) {
$classCheck = 0;
}else {
// match class C IP addresses
for ($i = 0; $i < 3; $i ++) {
if ($session_parts[$i] == $client_parts[$i]) {
$classCheck = 1;
continue;
} else {
$classCheck = 0;
break;
}
}
}
// we have a different IP address
if ($_SESSION[$session_var] != $clientIP && empty ($classCheck)) {
$GLOBALS['log']->fatal("IP Address mismatch: SESSION IP: {$_SESSION[$session_var]} CLIENT IP: {$clientIP}");
return false;
}
} else {
return false;
}
}
return true;
}
if(!function_exists("get_encoded")){
/*HELPER FUNCTIONS*/
function get_encoded($object){
return base64_encode(serialize($object));
}
function get_decoded($object){
return unserialize(base64_decode($object));
}
/**
* decrypt a string use the TripleDES algorithm. This meant to be
* modified if the end user chooses a different algorithm
*
* @param $string - the string to decrypt
*
* @return a decrypted string if we can decrypt, the original string otherwise
*/
function decrypt_string($string){
if(function_exists('mcrypt_cbc')){
require_once('modules/Administration/Administration.php');
$focus = new Administration();
$focus->retrieveSettings();
$key = '';
if(!empty($focus->settings['ldap_enc_key'])){
$key = $focus->settings['ldap_enc_key'];
}
if(empty($key))
return $string;
$buffer = $string;
$key = substr(md5($key),0,24);
$iv = "password";
return mcrypt_cbc(MCRYPT_3DES, $key, pack("H*", $buffer), MCRYPT_DECRYPT, $iv);
}else{
return $string;
}
}
}
function canViewPath( $path, $base ){
$path = realpath( $path );
$base = realpath( $base );
return 0 !== strncmp( $path, $base, strlen( $base ) );
}
/*END HELPER*/
?>

564
soap/SoapPortalHelper.php Executable file
View File

@@ -0,0 +1,564 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
$portal_modules = array('Contacts', 'Accounts', 'Cases', 'Bugs', 'Notes');
/*
BUGS
*/
require_once('modules/Notes/Note.php');
require_once('modules/Contacts/Contact.php');
require_once('modules/Bugs/Bug.php');
function get_bugs_in_contacts($in, $orderBy = '', $where='')
{
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
$query = "SELECT bug_id as id from contacts_bugs where contact_id IN $in AND deleted=0";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$sugar = new Contact();
set_module_in($sugar->build_related_in($query), 'Bugs');
}
function get_bugs_in_accounts($in, $orderBy = '', $where='')
{
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
$query = "SELECT bug_id as id from accounts_bugs where account_id IN $in AND deleted=0";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$sugar = new Account();
set_module_in($sugar->build_related_in($query), 'Bugs');
}
/*
Cases
*/
require_once('modules/Cases/Case.php');
function get_cases_in_contacts($in, $orderBy = '')
{
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
$query = "SELECT case_id as id from contacts_cases where contact_id IN $in AND deleted=0";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$sugar = new Contact();
set_module_in($sugar->build_related_in($query), 'Cases');
}
function get_cases_in_accounts($in, $orderBy = '')
{
if(empty($_SESSION['viewable']['Accounts'])){
return;
}
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
$query = "SELECT id from cases where account_id IN $in AND deleted=0";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$sugar = new Account();
set_module_in($sugar->build_related_in($query), 'Cases');
}
/*
NOTES
*/
require_once('modules/Accounts/Account.php');
function get_notes_in_contacts($in, $orderBy = '')
{
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
$query = "SELECT id from notes where contact_id IN $in AND deleted=0 AND portal_flag=1";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$contact = new Contact();
$note = new Note();
return $contact->build_related_list($query, $note);
}
function get_notes_in_module($in, $module, $orderBy = '')
{
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
$query = "SELECT id from notes where parent_id IN $in AND parent_type='$module' AND deleted=0 AND portal_flag = 1";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
global $beanList, $beanFiles;
if(!empty($beanList[$module])){
$class_name = $beanList[$module];
require_once($beanFiles[$class_name]);
$sugar = new $class_name();
}else{
return array();
}
$note = new Note();
return $sugar->build_related_list($query, $note);
}
function get_related_in_module($in, $module, $rel_module, $orderBy = '', $row_offset = 0, $limit= -1)
{
global $beanList, $beanFiles;
if(!empty($beanList[$rel_module])){
$class_name = $beanList[$rel_module];
require_once($beanFiles[$class_name]);
$rel = new $class_name();
}else{
return array();
}
//bail if the in is empty
if($in == '()')return;
// First, get the list of IDs.
if ($module == 'KBDocuments' || $module == 'DocumentRevisions') {
$query = "SELECT dr.* from document_revisions dr
inner join kbdocument_revisions kr on kr.document_revision_id = dr.id AND kr.kbdocument_id IN ($in)
AND dr.file_mime_type is not null";
} else {
$query = "SELECT id from $rel->table_name where parent_id IN $in AND parent_type='$module' AND deleted=0 AND portal_flag = 1";
}
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
if(!empty($beanList[$module])){
$class_name = $beanList[$module];
require_once($beanFiles[$class_name]);
$sugar = new $class_name();
}else{
return array();
}
$count_query = $sugar->create_list_count_query($query);
if(!empty($count_query))
{
// We have a count query. Run it and get the results.
$result = $sugar->db->query($count_query, true, "Error running count query for $sugar->object_name List: ");
$assoc = $sugar->db->fetchByAssoc($result);
if(!empty($assoc['c']))
{
$rows_found = $assoc['c'];
}
}
$list = $sugar->build_related_list($query, $rel, $row_offset, $limit);
$list['result_count'] = $rows_found;
return $list;
}
function get_accounts_from_contact($contact_id, $orderBy = '')
{
// First, get the list of IDs.
$query = "SELECT account_id as id from accounts_contacts where contact_id='$contact_id' AND deleted=0";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$sugar = new Contact();
set_module_in($sugar->build_related_in($query), 'Accounts');
}
function get_contacts_from_account($account_id, $orderBy = '')
{
// First, get the list of IDs.
$query = "SELECT contact_id as id from accounts_contacts where account_id='$account_id' AND deleted=0";
if(!empty($orderBy)){
$query .= ' ORDER BY ' . $orderBy;
}
$sugar = new Account();
set_module_in($sugar->build_related_in($query), 'Contacts');
}
function get_related_list($in, $template, $where, $order_by, $row_offset = 0, $limit = ""){
$list = array();
//bail if the in is empty
if($in == '()')return $list;
return $template->build_related_list_where('',$template, $where, $in, $order_by, $limit, $row_offset);
}
function build_relationship_tree($contact){
global $sugar_config;
$contact->retrieve($contact->id);
get_accounts_from_contact($contact->id);
set_module_in(array('list'=>array($contact->id), 'in'=> "('$contact->id')"), 'Contacts');
$accounts = $_SESSION['viewable']['Accounts'];
foreach($accounts as $id){
if(!isset($sugar_config['portal_view']) || $sugar_config['portal_view'] != 'single_user'){
get_contacts_from_account($id);
}
}
}
function get_contacts_in(){
return $_SESSION['viewable']['contacts_in'];
}
function get_accounts_in(){
return $_SESSION['viewable']['accounts_in'];
}
function get_module_in($module_name){
if(!isset($_SESSION['viewable'][$module_name])){
return '()';
}
$mod_in = "('" . join("','", array_keys($_SESSION['viewable'][$module_name])) . "')";
$_SESSION['viewable'][strtolower($module_name).'_in'] = $mod_in;
return $mod_in;
}
function set_module_in($arrayList, $module_name){
if(!isset($_SESSION['viewable'][$module_name])){
$_SESSION['viewable'][$module_name] = array();
}
foreach($arrayList['list'] as $id){
$_SESSION['viewable'][$module_name][$id] = $id;
}
if($module_name == 'Accounts' && isset($id)){
$_SESSION['account_id'] = $id;
}
if(!empty($_SESSION['viewable'][strtolower($module_name).'_in'])){
if($arrayList['in'] != '()') {
$_SESSION['viewable'][strtolower($module_name).'_in'] = "('" . implode("', '", $_SESSION['viewable'][strtolower($module_name).'_in']);
$_SESSION['viewable'][strtolower($module_name).'_in'] .= implode("', '", $arrayList['list']) . "')";
}
}else{
$_SESSION['viewable'][strtolower($module_name).'_in'] = $arrayList['in'];
}
}
/*
* Given the user auth, attempt to log the user in.
* used by SoapPortalUsers.php
*/
function login_user($portal_auth){
$error = new SoapError();
$user = new User();
$user = $user->retrieve_by_string_fields(array('user_name'=>$portal_auth['user_name'],'user_hash'=>$portal_auth['password'], 'deleted'=>0, 'status'=>'Active', 'portal_only'=>1) );
if($user != null){
global $current_user;
$current_user = $user;
return 'success';
}else{
return 'fail';
}
}
function portal_get_entry_list_limited($session, $module_name,$where, $order_by, $select_fields, $row_offset, $limit){
global $beanList, $beanFiles, $portal_modules;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' ){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($module_name == 'Cases'){
if(!isset($_SESSION['viewable'][$module_name])){
get_cases_in_contacts(get_contacts_in());
get_cases_in_accounts(get_accounts_in());
}
$sugar = new aCase();
$list = get_related_list(get_module_in($module_name), new aCase(), $where,$order_by, $row_offset, $limit);
}else if($module_name == 'Contacts'){
$sugar = new Contact();
$list = get_related_list(get_module_in($module_name), new Contact(), $where,$order_by);
}else if($module_name == 'Accounts'){
$sugar = new Account();
$list = get_related_list(get_module_in($module_name), new Account(), $where,$order_by);
}else if($module_name == 'Bugs'){
if(!isset($_SESSION['viewable'][$module_name])){
get_bugs_in_contacts(get_contacts_in());
get_bugs_in_accounts(get_accounts_in());
}
$list = get_related_list(get_module_in($module_name), new Bug(), $where, $order_by, $row_offset, $limit);
} else if ($module_name == 'KBDocuments') {
} else if ($module_name == 'FAQ') {
} else{
$error->set_error('no_module_support');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$output_list = Array();
$field_list = array();
foreach($list as $value)
{
//$loga->fatal("Adding another account to the list");
$output_list[] = get_return_value($value, $module_name);
$_SESSION['viewable'][$module_name][$value->id] = $value->id;
if(empty($field_list)){
$field_list = get_field_list($value);
}
}
$output_list = filter_return_list($output_list, $select_fields, $module_name);
$field_list = filter_field_list($field_list,$select_fields, $module_name);
return array('result_count'=>sizeof($output_list), 'next_offset'=>0,'field_list'=>$field_list, 'entry_list'=>$output_list, 'error'=>$error->get_soap_array());
}
$invalid_contact_fields = array('portal_name'=>1, 'portal_password'=>1, 'portal_active'=>1);
$valid_modules_for_contact = array('Contacts'=>1, 'Cases'=>1, 'Notes'=>1, 'Bugs'=>1, 'Accounts'=>1, 'Leads'=>1, 'KBDocuments'=>1);
?>

946
soap/SoapPortalUsers.php Executable file
View File

@@ -0,0 +1,946 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('soap/SoapHelperFunctions.php');
require_once('soap/SoapTypes.php');
require_once('modules/Contacts/Contact.php');
require_once('modules/Accounts/Account.php');
require_once('soap/SoapPortalHelper.php');
require_once('include/SugarEmailAddress/SugarEmailAddress.php');
require_once('config.php');
/*************************************************************************************
THIS IS FOR PORTAL USERS
*************************************************************************************/
/*
this authenticates a user as a portal user and returns the session id or it returns false otherwise;
*/
$server->register(
'portal_login',
array('portal_auth'=>'tns:user_auth','user_name'=>'xsd:string', 'application_name'=>'xsd:string'),
array('return'=>'tns:set_entry_result'),
$NAMESPACE);
function portal_login($portal_auth, $user_name, $application_name){
$error = new SoapError();
$contact = new Contact();
$result = login_user($portal_auth);
if($result == 'fail' || $result == 'sessions_exceeded'){
if($result == 'sessions_exceeded') {
$error->set_error('sessions_exceeded');
}
else {
$error->set_error('no_portal');
}
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
global $current_user;
if($user_name == 'lead'){
session_start();
$_SESSION['is_valid_session']= true;
$_SESSION['ip_address'] = query_client_ip();
$_SESSION['portal_id'] = $current_user->id;
$_SESSION['type'] = 'lead';
login_success();
return array('id'=>session_id(), 'error'=>$error->get_soap_array());
}else if($user_name == 'portal'){
session_start();
$_SESSION['is_valid_session']= true;
$_SESSION['ip_address'] = query_client_ip();
$_SESSION['portal_id'] = $current_user->id;
$_SESSION['type'] = 'portal';
$GLOBALS['log']->debug("Saving new session");
login_success();
return array('id'=>session_id(), 'error'=>$error->get_soap_array());
}else{
$contact = $contact->retrieve_by_string_fields(array('portal_name'=>$user_name, 'portal_active'=>'1', 'deleted'=>0) );
if($contact != null){
session_start();
$_SESSION['is_valid_session']= true;
$_SESSION['ip_address'] = query_client_ip();
$_SESSION['user_id'] = $contact->id;
$_SESSION['portal_id'] = $current_user->id;
$_SESSION['type'] = 'contact';
$_SESSION['assigned_user_id'] = $contact->assigned_user_id;
login_success();
build_relationship_tree($contact);
return array('id'=>session_id(), 'error'=>$error->get_soap_array());
}
}
$error->set_error('invalid_login');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
/*
this validates the session and starts the session;
*/
function portal_validate_authenticated($session_id){
$old_error_reporting = error_reporting(0);
session_id($session_id);
// This little construct checks to see if the session validated
if(session_start()) {
$valid_session = true;
if(!empty($_SESSION['is_valid_session']) && is_valid_ip_address('ip_address') && $valid_session != null && ($_SESSION['type'] == 'contact' || $_SESSION['type'] == 'lead' || $_SESSION['type'] == 'portal')){
global $current_user;
$current_user = new User();
$current_user->retrieve($_SESSION['portal_id']);
login_success();
error_reporting($old_error_reporting);
return true;
}
}
session_destroy();
error_reporting($old_error_reporting);
return false;
}
$server->register(
'portal_logout',
array('session'=>'xsd:string'),
array('return'=>'tns:error_value'),
$NAMESPACE);
function portal_logout($session){
$error = new SoapError();
if(portal_validate_authenticated($session)){
session_destroy();
return $error->get_soap_array();
}
$error->set_error('invalid_session');
return $error->get_soap_array();
}
$server->register(
'portal_get_sugar_id',
array('session'=>'xsd:string'),
array('return'=>'tns:set_entry_result'),
$NAMESPACE);
function portal_get_sugar_id($session){
$error = new SoapError();
if(portal_validate_authenticated($session)){
return array('id'=>$_SESSION['portal_id'], 'error'=>$error->get_soap_array());
}
$error->set_error('invalid_session');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
$server->register(
'portal_get_sugar_contact_id',
array('session'=>'xsd:string'),
array('return'=>'tns:set_entry_result'),
$NAMESPACE);
function portal_get_sugar_contact_id($session){
$error = new SoapError();
if(portal_validate_authenticated($session)){
return array('id'=>$_SESSION['user_id'], 'error'=>$error->get_soap_array());
}
$error->set_error('invalid_session');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
$server->register(
'portal_get_entry_list',
array('session'=>'xsd:string', 'module_name'=>'xsd:string','where'=>'xsd:string', 'order_by'=>'xsd:string', 'select_fields'=>'tns:select_fields'),
array('return'=>'tns:get_entry_list_result'),
$NAMESPACE);
function portal_get_entry_list($session, $module_name,$where, $order_by, $select_fields){
return portal_get_entry_list_limited($session, $module_name, $where, $order_by, $select_fields, 0, "");
}
/*
* Acts like a normal get_entry_list except it will build the where clause based on the name_value pairs passed
* Here we assume 'AND'
*/
$server->register(
'portal_get_entry_list_filter',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'order_by'=>'xsd:string', 'select_fields'=>'tns:select_fields', 'row_offset' => 'xsd:int', 'limit'=>'xsd:int', 'filter' =>'tns:name_value_operator_list'),
array('return'=>'tns:get_entry_list_result'),
$NAMESPACE);
function portal_get_entry_list_filter($session, $module_name, $order_by, $select_fields, $row_offset, $limit, $filter){
global $beanList, $beanFiles, $portal_modules;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead'){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
//build the where clause
$sugar = null;
if($module_name == 'Cases'){
$sugar = new aCase();
}else if($module_name == 'Contacts'){
$sugar = new Contact();
}else if($module_name == 'Accounts'){
$sugar = new Account();
}else if($module_name == 'Bugs'){
$sugar = new Bug();
} else if($module_name == 'KBDocuments' || $module_name == 'FAQ') {
$sugar = new KBDocument();
} else {
$error->set_error('no_module_support');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($sugar != null){
if(isset($filter) && is_array($filter)){
$where = "";
foreach($filter as $nvOp){
$name = $nvOp['name'];
$value = $nvOp['value'];
$value_array = $nvOp['value_array'];
$operator = $nvOp['operator'];
//do nothing if all three values are not set
if(isset($name) && (isset($value) || isset($value_array)) && isset($operator)){
if(!empty($where)){
$where .= ' AND ';
}
if(isset($sugar->field_defs[$name])){
// MFH - Added Support For Custom Fields in Searches
$cstm = isset($sugar->field_defs[$name]['source']) && $sugar->field_defs[$name]['source'] == 'custom_fields' ? '_cstm' : '';
$where .= "$sugar->table_name$cstm.$name $operator ";
if($sugar->field_defs['name']['type'] == 'datetime'){
$where .= db_convert("'$value'", 'datetime');
}else{
if(empty($value)) {
$tmp = array();
foreach($value_array as $v) {
$tmp[] = $GLOBALS['db']->quote($v);
}
$where .= "('" . implode("', '", $tmp) . "')";
} else {
$where .= "'".$GLOBALS['db']->quote($value)."'";
}
}
}
}
}
}
return portal_get_entry_list_limited($session, $module_name, $where, $order_by, $select_fields, $row_offset, $limit);
}else{
$error->set_error('no_module_support');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
}
$server->register(
'portal_get_entry',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'id'=>'xsd:string', 'select_fields'=>'tns:select_fields'),
array('return'=>'tns:get_entry_result'),
$NAMESPACE);
function portal_get_entry($session, $module_name, $id,$select_fields ){
global $beanList, $beanFiles;
$error = new SoapError();
if(!portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead'){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($_SESSION['viewable'][$module_name][$id])){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
$seed->retrieve($id);
if($module_name == 'KBDocuments') {
$body = $seed->get_kbdoc_body($id);
$seed->description = $body;
}
$output_list = Array();
$output_list[] = get_return_value($seed, $module_name);
//$output_list[0]['name_value_list']['description'] = array('name'=>'description', 'value'=>$seed->description);
//$output_list = filter_return_list($output_list, $select_fields, $module_name);
$field_list = array();
if(empty($field_list)){
$field_list = get_field_list($seed, true);
}
$output_list = filter_return_list($output_list, $select_fields, $module_name);
$field_list = filter_field_list($field_list,$select_fields, $module_name);
return array('field_list'=>$field_list, 'entry_list'=>$output_list, 'error'=>$error->get_soap_array());
}
$server->register(
'portal_set_entry',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'name_value_list'=>'tns:name_value_list'),
array('return'=>'tns:set_entry_result'),
$NAMESPACE);
function portal_set_entry($session,$module_name, $name_value_list){
global $beanList, $beanFiles, $valid_modules_for_contact;
$error = new SoapError();
if(!portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' && $module_name != 'Leads'){
$error->set_error('no_access');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'contact' && !key_exists($module_name, $valid_modules_for_contact) ){
$error->set_error('no_access');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
$is_update = false;
$values_set = array();
foreach($name_value_list as $value){
if($value['name'] == 'id' && !empty($value['value'])) {
$seed->disable_row_level_security = true;
$seed->retrieve($value['value']);
$is_update = true;
break;
}
$values_set[$value['name']] = $value['value'];
$seed->$value['name'] = $value['value'];
}
// If it was an update, we have to set the values again
if($is_update) {
foreach($name_value_list as $value){
$seed->$value['name'] = $value['value'];
}
}
if(!isset($_SESSION['viewable'][$module_name])){
$_SESSION['viewable'][$module_name] = array();
}
if(!$is_update){
if(isset($_SESSION['assigned_user_id']) && (!key_exists('assigned_user_id', $values_set) || empty($values_set['assigned_user_id']))){
$seed->assigned_user_id = $_SESSION['assigned_user_id'];
}
if(isset($_SESSION['account_id']) && (!key_exists('account_id', $values_set) || empty($values_set['account_id']))){
$seed->account_id = $_SESSION['account_id'];
}
$seed->portal_flag = 1;
$seed->portal_viewable = true;
}
$id = $seed->save();
set_module_in(array('in'=>"('$id')", 'list'=>array($id)), $module_name);
if($_SESSION['type'] == 'contact' && $module_name != 'Contacts' && !$is_update){
if($module_name == 'Notes'){
$seed->contact_id = $_SESSION['user_id'];
if(isset( $_SESSION['account_id'])){
$seed->parent_type = 'Accounts';
$seed->parent_id = $_SESSION['account_id'];
}
$id = $seed->save();
}else{
$seed->contact_id = $_SESSION['user_id'];
if(isset( $_SESSION['account_id'])){
$seed->account_id = $_SESSION['account_id'];
}
$seed->save_relationship_changes(false);
}
}
return array('id'=>$id, 'error'=>$error->get_soap_array());
}
/*
NOTE SPECIFIC CODE
*/
$server->register(
'portal_set_note_attachment',
array('session'=>'xsd:string','note'=>'tns:note_attachment'),
array('return'=>'tns:set_entry_result'),
$NAMESPACE);
function portal_set_note_attachment($session,$note)
{
$error = new SoapError();
if(!portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('id'=>'-1', 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' || !isset($_SESSION['viewable']['Notes'][$note['id']])){
$error->set_error('no_access');
return array('id'=>-1, 'error'=>$error->get_soap_array());
}
require_once('modules/Notes/NoteSoap.php');
$ns = new NoteSoap();
$id = $ns->saveFile($note, true);
return array('id'=>$id, 'error'=>$error->get_soap_array());
}
$server->register(
'portal_remove_note_attachment',
array('session'=>'xsd:string', 'id'=>'xsd:string'),
array('return'=>'tns:error_value'),
$NAMESPACE);
function portal_remove_note_attachment($session, $id)
{
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' || !isset($_SESSION['viewable']['Notes'][$id])){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
require_once('modules/Notes/Note.php');
$focus = new Note();
$focus->retrieve($id);
$result = $focus->deleteAttachment();
return $error->get_soap_array();
}
$server->register(
'portal_get_note_attachment',
array('session'=>'xsd:string', 'id'=>'xsd:string'),
array('return'=>'tns:return_note_attachment'),
$NAMESPACE);
function portal_get_note_attachment($session,$id)
{
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' || !isset($_SESSION['viewable']['Notes'][$id])){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$current_user = $seed_user;
require_once('modules/Notes/Note.php');
$note = new Note();
$note->retrieve($id);
require_once('modules/Notes/NoteSoap.php');
$ns = new NoteSoap();
if(!isset($note->filename)){
$note->filename = '';
}
$file= $ns->retrieveFile($id,$note->filename);
if($file == -1){
$error->set_error('no_file');
$file = '';
}
return array('note_attachment'=>array('id'=>$id, 'filename'=>$note->filename, 'file'=>$file), 'error'=>$error->get_soap_array());
}
$server->register(
'portal_relate_note_to_module',
array('session'=>'xsd:string', 'note_id'=>'xsd:string', 'module_name'=>'xsd:string', 'module_id'=>'xsd:string'),
array('return'=>'tns:error_value'),
$NAMESPACE);
function portal_relate_note_to_module($session,$note_id, $module_name, $module_id){
global $beanList, $beanFiles, $current_user;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return $error->get_soap_array();
}
if($_SESSION['type'] == 'lead' || !isset($_SESSION['viewable']['Notes'][$note_id]) || !isset($_SESSION['viewable'][$module_name][$module_id])){
$error->set_error('no_access');
return $error->get_soap_array();
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return $error->get_soap_array();
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
$seed->retrieve($module_id);
if($module_name == 'Cases' || $module_name == 'Bugs') {
$seed->note_id = $note_id;
$seed->save(false);
} else {
$error->set_error('no_module_support');
$error->description .= ': '. $module_name;
}
return $error->get_soap_array();
}
$server->register(
'portal_get_related_notes',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'module_id'=>'xsd:string', 'select_fields'=>'tns:select_fields', 'order_by'=>'xsd:string'),
array('return'=>'tns:get_entry_result'),
$NAMESPACE);
function portal_get_related_notes($session,$module_name, $module_id, $select_fields, $order_by){
global $beanList, $beanFiles;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' ){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($_SESSION['viewable'][$module_name][$module_id])){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($module_name =='Contacts'){
if($_SESSION['user_id'] != $module_id){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$list = get_notes_in_contacts("('$module_id')", $order_by);
}else{
$list = get_notes_in_module("('$module_id')", $module_name, $order_by);
}
$output_list = Array();
$field_list = Array();
foreach($list as $value)
{
$output_list[] = get_return_value($value, 'Notes');
$_SESSION['viewable']['Notes'][$value->id] = $value->id;
if(empty($field_list)){
$field_list = get_field_list($value, true);
}
}
$output_list = filter_return_list($output_list, $select_fields, $module_name);
$field_list = filter_field_list($field_list,$select_fields, $module_name);
return array('result_count'=>sizeof($output_list), 'next_offset'=>0,'field_list'=>$field_list, 'entry_list'=>$output_list, 'error'=>$error->get_soap_array());
}
$server->register(
'portal_get_related_list',
array('session'=>'xsd:string', 'module_name'=>'xsd:string', 'rel_module'=>'xsd:string', 'module_id'=>'xsd:string', 'select_fields'=>'tns:select_fields', 'order_by'=>'xsd:string', 'offset' => 'xsd:int', 'limit' => 'xsd:int'),
array('return'=>'tns:get_entry_result'),
$NAMESPACE);
function portal_get_related_list($session, $module_name, $rel_module, $module_id, $select_fields, $order_by, $offset, $limit){
global $beanList, $beanFiles;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' ){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
if(empty($_SESSION['viewable'][$module_name][$module_id])){
$error->set_error('no_access');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
$list = get_related_in_module("('$module_id')", $module_name, $rel_module, $order_by, $offset, $limit);
$output_list = Array();
$field_list = Array();
foreach($list as $value)
{
$output_list[] = get_return_value($value, $rel_module);
$_SESSION['viewable'][$rel_module][$value->id] = $value->id;
if(empty($field_list)){
$field_list = get_field_list($value, true);
}
}
$output_list = filter_return_list($output_list, $select_fields, $module_name);
$field_list = filter_field_list($field_list,$select_fields, $module_name);
return array('result_count'=>$list['result_count'], 'next_offset'=>0,'field_list'=>$field_list, 'entry_list'=>$output_list, 'error'=>$error->get_soap_array());
}
$server->register(
'portal_get_module_fields',
array('session'=>'xsd:string', 'module_name'=>'xsd:string'),
array('return'=>'tns:module_fields'),
$NAMESPACE);
function portal_get_module_fields($session, $module_name){
global $beanList, $beanFiles, $portal_modules, $valid_modules_for_contact;
$error = new SoapError();
$module_fields = array();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
$error->description .=$session;
return array('module_name'=>$module_name, 'module_fields'=>$module_fields, 'error'=>$error->get_soap_array());
}
if($_SESSION['type'] == 'lead' && $module_name != 'Leads'){
$error->set_error('no_access');
return array('module_name'=>$module_name, 'module_fields'=>$module_fields, 'error'=>$error->get_soap_array());
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return array('module_name'=>$module_name, 'module_fields'=>$module_fields, 'error'=>$error->get_soap_array());
}
if(($_SESSION['type'] == 'portal'||$_SESSION['type'] == 'contact') && !key_exists($module_name, $valid_modules_for_contact)){
$error->set_error('no_module');
return array('module_name'=>$module_name, 'module_fields'=>$module_fields, 'error'=>$error->get_soap_array());
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
$seed->fill_in_additional_detail_fields();
$returnFields = get_return_module_fields($seed, $module_name, $error->get_soap_array(), true);
if(is_subclass_of($seed, 'Person')) {
$returnFields['module_fields']['email1'] = array('name'=>'email1', 'type'=>'email', 'required'=>0, 'label'=>translate('LBL_EMAIL_ADDRESS', $seed->module_dir));
$returnFields['module_fields']['email_opt_out'] = array('name'=>'email_opt_out', 'type'=>'bool', 'required'=>0, 'label'=>translate('LBL_EMAIL_OPT_OUT', $seed->module_dir), 'options'=>array());
} //if
return $returnFields;
}
$server->register(
'portal_get_subscription_lists',
array('session'=>'xsd:string'),
array('return'=>'tns:get_subscription_lists_result'),
$NAMESPACE);
function portal_get_subscription_lists($session){
global $beanList, $beanFiles;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
require_once('modules/Campaigns/utils.php');
$contact = new Contact();
$contact->retrieve($_SESSION['user_id']);
if(!empty($contact->id)) {
$result = get_subscription_lists_keyed($contact, true);
}
$return_results = array('unsubscribed' => array(), 'subscribed' => array());
foreach($result['unsubscribed'] as $newsletter_name => $data) {
$return_results['unsubscribed'][] = array('name' => $newsletter_name, 'prospect_list_id' => $data['prospect_list_id'],
'campaign_id' => $data['campaign_id'], 'description' => $data['description'],
'frequency' => $data['frequency']);
}
foreach($result['subscribed'] as $newsletter_name => $data) {
$return_results['subscribed'][] = array('name' => $newsletter_name, 'prospect_list_id' => $data['prospect_list_id'],
'campaign_id' => $data['campaign_id'], 'description' => $data['description'],
'frequency' => $data['frequency']);
}
return array('unsubscribed'=>$return_results['unsubscribed'], 'subscribed' => $return_results['subscribed'], 'error'=>$error->get_soap_array());
}
$server->register(
'portal_set_newsletters',
array('session'=>'xsd:string', 'subscribe_ids' => 'tns:select_fields', 'unsubscribe_ids' => 'tns:select_fields'),
array('return'=>'tns:error_value'),
$NAMESPACE);
function portal_set_newsletters($session, $subscribe_ids, $unsubscribe_ids){
global $beanList, $beanFiles;
$error = new SoapError();
if(! portal_validate_authenticated($session)){
$error->set_error('invalid_session');
return array('result_count'=>-1, 'entry_list'=>array(), 'error'=>$error->get_soap_array());
}
require_once('modules/Campaigns/utils.php');
$contact = new Contact();
$contact->retrieve($_SESSION['user_id']);
if(!empty($contact->id)) {
foreach($subscribe_ids as $campaign_id) {
subscribe($campaign_id, null, $contact, true);
}
foreach($unsubscribe_ids as $campaign_id) {
unsubscribe($campaign_id, $contact);
}
}
return $error->get_soap_array();
}
?>

508
soap/SoapRelationshipHelper.php Executable file
View File

@@ -0,0 +1,508 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('soap/SoapError.php');
function check_for_relationship($relationships, $module){
foreach($relationships as $table=>$rel){
if( $rel['rhs_key'] == $module){
return $table;
}
}
return false;
}
/*
* takes in two modules and returns the relationship information about them
*
*/
function retrieve_relationships_properties($module_1, $module_2, $relationship_name = ""){
require_once('modules/Relationships/Relationship.php');
$rs = new Relationship();
$query = "SELECT * FROM $rs->table_name WHERE ((lhs_module = '$module_1' AND rhs_module='$module_2') OR (lhs_module = '$module_2' AND rhs_module='$module_1'))";
if(!empty($relationship_name) && isset($relationship_name)){
$query .= " AND relationship_name = '$relationship_name'";
}
$result = $rs->db->query($query);
return $rs->db->fetchByAssoc($result);
}
/*
* retireves relationships between two modules
* This will return all viewable relationships between two modules
* module_query is a filter on the first module
* related_module_query is a filter on the second module
* relationship_query is a filter on the relationship between them
* show_deleted is if deleted items should be shown or not
*
*/
function retrieve_relationships($module_name, $related_module, $relationship_query, $show_deleted, $offset, $max_results){
global $beanList, $beanFiles, $dictionary, $current_user;
$error = new SoapError();
$result_list = array();
if(empty($beanList[$module_name]) || empty($beanList[$related_module])){
$error->set_error('no_module');
return array('result'=>$result_list, 'error'=>$error->get_soap_array());
}
$result = retrieve_relationship_query($module_name, $related_module, $relationship_query, $show_deleted, $offset, $max_results);
if(empty($result['module_1'])){
$error->set_error('no_relationship_support');
return array('result'=>$result_list, 'error'=>$error->get_soap_array());
}
$query = $result['query'];
$module_1 = $result['module_1'];
$table = $result['join_table'];
$class_name = $beanList[$module_1];
require_once($beanFiles[$class_name]);
$mod = new $class_name();
$count_query = str_replace('rt.*', 'count(*)', $query);
$result = $mod->db->query($count_query);
$row = $mod->db->fetchByAssoc($result);
$total_count = $row['count(*)'];
if($max_results != '-99'){
$result = $mod->db->limitQuery($query, $offset, $max_results);
}else{
$result = $mod->db->query($query);
}
while($row = $mod->db->fetchByAssoc($result)){
$result_list[] = $row;
}
return array('table_name'=>$table, 'result'=>$result_list, 'total_count'=>$total_count, 'error'=>$error->get_soap_array());
}
/*
* retireves modified relationships between two modules
* This will return all viewable relationships between two modules
* module_query is a filter on the first module
* related_module_query is a filter on the second module
* relationship_query is a filter on the relationship between them
* show_deleted is if deleted items should be shown or not
*
*/
function retrieve_modified_relationships($module_name, $related_module, $relationship_query, $show_deleted, $offset, $max_results, $select_fields = array(), $relationship_name = ''){
global $beanList, $beanFiles, $dictionary, $current_user;
$error = new SoapError();
$result_list = array();
if(empty($beanList[$module_name]) || empty($beanList[$related_module])){
$error->set_error('no_module');
return array('result'=>$result_list, 'error'=>$error->get_soap_array());
}
$row = retrieve_relationships_properties($module_name, $related_module, $relationship_name);
if(empty($row)){
$error->set_error('no_relationship_support');
return array('result'=>$result_list, 'error'=>$error->get_soap_array());
}
$table = $row['join_table'];
$has_join = true;
if(empty($table)){
//return array('table_name'=>$table, 'result'=>$result_list, 'error'=>$error->get_soap_array());
$table = $row['rhs_table'];
$module_1 = $row['lhs_module'];
$mod_key = $row['lhs_key'];
$module_2 = $row['rhs_module'];
$mod2_key = $row['rhs_key'];
$has_join = false;
}
else{
$module_1 = $row['lhs_module'];
$mod_key = $row['join_key_lhs'];
$module_2 = $row['rhs_module'];
$mod2_key = $row['join_key_rhs'];
}
$class_name = $beanList[$module_1];
require_once($beanFiles[$class_name]);
$mod = new $class_name();
$mod2_name = $beanList[$module_2];
require_once($beanFiles[$mod2_name]);
$mod2 = new $mod2_name();
$table_alias = 'rt';
if($has_join == false){
$table_alias = 'm1';
}
if(isset($select_fields) && !empty($select_fields)){
$index = 0;
$field_select ='';
foreach($select_fields as $field){
if($field == "id"){
$field_select .= "DISTINCT m1.".$field;
}
else{
if(strpos($field, ".") == false){
$field_select .= "m1.".$field;
}
else{
$field_select .= $field;
}
}
if($index < (count($select_fields) - 1))
{
$field_select .= ",";
$index++;
}
}//end foreach
$query = "SELECT $field_select FROM $table $table_alias ";
}
else{
$query = "SELECT rt.* FROM $table $table_alias ";
}
if($has_join == false){
$query .= " inner join $mod->table_name m2 on $table_alias.$mod2_key = m2.id ";
}
else{
$query .= " inner join $mod->table_name m1 on rt.$mod_key = m1.id ";
$query .= " inner join $mod2->table_name m2 on rt.$mod2_key = m2.id AND m2.id = '$current_user->id'";
}
if(!empty($relationship_query)){
$query .= ' WHERE ' . string_format($relationship_query, array($table_alias));
}
if($max_results != '-99'){
$result = $mod->db->limitQuery($query, $offset, $max_results);
}else{
$result = $mod->db->query($query);
}
while($row = $mod->db->fetchByAssoc($result)){
$result_list[] = $row;
}
return array('table_name'=>$table, 'result'=>$result_list, 'total_count'=>$total_count, 'error'=>$error->get_soap_array());
}
/*
* retireves relationships between two modules
* This will return all viewable relationships between two modules
* module_query is a filter on the first module
* related_module_query is a filter on the second module
* relationship_query is a filter on the relationship between them
* show_deleted is if deleted items should be shown or not
*
*/
function clear_relationships($module_name, $related_module){
global $beanList, $beanFiles, $dictionary;
$result_list = array();
if(empty($beanList[$module_name]) || empty($beanList[$related_module])){
return false;
}
$row = retrieve_relationships_properties($module_name, $related_module);
if(empty($row)){
return false;
}
if($module_name == $row['lhs_module']){
$module_1 = $module_name;
$module_2 = $related_module;
}else{
$module_2 = $module_name;
$module_1 = $related_module;
}
$table = $row['join_table'];
$class_name = $beanList[$module_1];
require_once($beanFiles[$class_name]);
$mod = new $class_name();
$clear_query = "DELTE * FROM $table WHERE 1=1";
$result = $mod->db->query($clear_query);
return true;
}
function server_save_relationships($list, $from_date, $to_date){
require_once('include/utils/db_utils.php');
global $beanList, $beanFiles;
$from_date = db_convert("'".$from_date."'", 'datetime');
$to_date = db_convert("'".$to_date."'", 'datetime');
global $sugar_config;
$db = DBManagerFactory::getInstance();
$ids = array();
$add = 0;
$modify = 0;
$deleted = 0;
foreach($list as $record)
{
$insert = '';
$insert_values = '';
$update = '';
$select_values = '';
$args = array();
$id = $record['id'];
$table_name = $record['module_name'];
$resolve = 1;
foreach($record['name_value_list'] as $name_value){
$name = $name_value['name'];
if($name == 'date_modified'){
$value = $to_date;
}else{
$value = db_convert("'".$name_value['value'] . "'", 'varchar');
}
if($name != 'resolve'){
if(empty($insert)){
$insert = '(' .$name;
$insert_values = '(' .$value;
if($name != 'date_modified' && $name != 'id' ){
$select_values = $name ."=$value";
}
if($name != 'id'){
$update = $name ."=$value";
}
}else{
$insert .= ', ' .$name;
$insert_values .= ', ' .$value;
if(empty($update)){
$update = $name."=$value";
}else{
$update = ','.$name."=$value";
}
if($name != 'date_modified' && $name != 'id' ){
if(empty($select_values)){
$select_values = $name ."=$value";
}else{
$select_values .= ' AND '.$name ."=$value";
}
}
}
}else{
$resolve = $value;
}
}
//ignore resolve for now server always wins
$resolve = 1;
$insert = "INSERT INTO $table_name $insert) VALUES $insert_values)";
$update = "UPDATE $table_name SET $update WHERE id=";
$delete = "DELETE FROM $table_name WHERE id=";
$select_by_id_date = "SELECT id FROM $table_name WHERE id ='$id' AND date_modified > $from_date AND date_modified<= $to_date";
$select_by_id = "SELECT id FROM $table_name WHERE id ='$id'";
$select_by_values = "SELECT id FROM $table_name WHERE $select_values";
$updated = false;
$result = $db->query($select_by_id_date);
//see if we have a matching id in the date_range
if(!($row = $db->fetchByAssoc($result))){
//if not lets check if we have one that matches the values
$result = $db->query($select_by_values);
if(!($row = $db->fetchByAssoc($result))){
$result = $db->query($select_by_id);
if($row = $db->fetchByAssoc($result)){
$db->query($update ."'".$row['id']."'" );
$ids[] = $row['id'];
$modify++;
}else{
$db->query($insert);
$add++;
$ids[] = $row['id'];
}
}
}
}
return array('add'=>$add, 'modify'=>$modify, 'ids'=>$ids);
}
/*
*
* gets the from statement from a query without the order by and without the select
*
*/
function get_from_statement($query){
$query = explode('FROM', $query);
if(sizeof($query) == 1){
$query = explode('from', $query[0]);
}
$query = explode( 'ORDER BY',$query[1]);
return ' FROM ' . $query[0];
}
function retrieve_relationship_query($module_name, $related_module, $relationship_query, $show_deleted, $offset, $max_results){
global $beanList, $beanFiles, $dictionary, $current_user;
$error = new SoapError();
$result_list = array();
if(empty($beanList[$module_name]) || empty($beanList[$related_module])){
$error->set_error('no_module');
return array('query' =>"", 'module_1'=>"", 'join_table' =>"", 'error'=>$error->get_soap_array());
}
$row = retrieve_relationships_properties($module_name, $related_module);
if(empty($row)){
$error->set_error('no_relationship_support');
return array('query' =>"", 'module_1'=>"", 'join_table' =>"", 'error'=>$error->get_soap_array());
}
$module_1 = $row['lhs_module'];
$mod_key = $row['join_key_lhs'];
$module_2 = $row['rhs_module'];
$mod2_key = $row['join_key_rhs'];
$table = $row['join_table'];
if(empty($table)){
return array('query' =>"", 'module_1'=>"", 'join_table' =>"", 'error'=>$error->get_soap_array());
}
$class_name = $beanList[$module_1];
require_once($beanFiles[$class_name]);
$mod = new $class_name();
$mod2_name = $beanList[$module_2];
require_once($beanFiles[$mod2_name]);
$mod2 = new $mod2_name();
$query = "SELECT rt.* FROM $table rt ";
$query .= " inner join $mod->table_name m1 on rt.$mod_key = m1.id ";
$query .= " inner join $mod2->table_name m2 on rt.$mod2_key = m2.id ";
if(!empty($relationship_query)){
$query .= ' WHERE ' . $relationship_query;
}
return array('query' =>$query, 'module_1'=>$module_1, 'join_table' => $table, 'error'=>$error->get_soap_array());
}
// Returns name of 'link' field between two given modules
function get_module_link_field($module_1, $module_2) {
global $beanList, $beanFiles;
// check to make sure both modules exist
if (empty($beanList[$module_1]) || empty($beanList[$module_2])) {
return FALSE;
}
$class_1 = $beanList[$module_1];
require_once($beanFiles[$class_1]);
$obj_1 = new $class_1();
// loop through link fields of $module_1, checking for a link to $module_2
foreach ($obj_1->get_linked_fields() as $linked_field) {
$obj_1->load_relationship($linked_field['name']);
$field = $linked_field['name'];
if (empty($obj_1->$field)) {
continue;
}
if ($obj_1->$field->getRelatedModuleName() == $module_2) {
return $field;
}
}
return FALSE;
}
// Retrieves array of ids for records of $get_module linked to $from_module by $get_id
// Example: to retrieve list of Contacts associated to Account X: $return = get_linked_records("Contacts", "Accounts", "X");
function get_linked_records($get_module, $from_module, $get_id) {
global $beanList, $beanFiles;
// instantiate and retrieve $from_module
$from_class = $beanList[$from_module];
require_once($beanFiles[$from_class]);
$from_mod = new $from_class();
$from_mod->retrieve($get_id);
$field = get_module_link_field($from_module, $get_module);
if ($field === FALSE) {
return FALSE;
}
$from_mod->load_relationship($field);
$id_arr = $from_mod->$field->get();
return $id_arr;
}
?>

318
soap/SoapStudio.php Executable file
View File

@@ -0,0 +1,318 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
// this is a list of what values are expected for a given custom field type
// will eventually be moved to the SugarFields classes
$custom_field_meta = array(
'address' => array(
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'len',
'name',
'reportable'
),
'bool' => array(
'duplicate_merge',
'help',
'label',
'label_value',
'name',
'reportable'
),
'currency' => array(
'duplicate_merge',
'help',
'label',
'label_value',
'name',
'reportable'
),
'date' => array(
'audited',
'default_value',
'duplicate_merge',
'help',
'label',
'label_value',
'massupdate',
'name',
'reportable',
'required'
),
'enum' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'massupdate',
'name',
'options',
'reportable',
'required'
),
'float' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'len',
'name',
'precision',
'reportable',
'required'
),
'html' => array(
'audited',
'duplicate_merge',
'ext4',
'help',
'label',
'label_value',
'name',
'reportable',
'required'
),
'int' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'len',
'max',
'min',
'name',
'reportable',
'required'
),
'multienum' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'massupdate',
'name',
'options',
'reportable',
'required'
),
'phone' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'len',
'name',
'reportable',
'required'
),
'radioenum' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'massupdate',
'name',
'options',
'reportable',
'required'
),
'relate' => array(
'audited',
'duplicate_merge',
'ext2',
'help',
'label',
'label_value',
'name',
'reportable',
'required'
),
'text' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'name',
'reportable',
'required'
),
'varchar' => array(
'audited',
'default',
'duplicate_merge',
'help',
'label',
'label_value',
'len',
'name',
'reportable',
'required'
)
);
// create or update an existing custom field
$server->register(
'set_custom_field',
array(
'session' => 'xsd:string',
'module_name' => 'xsd:string',
'type' => 'xsd:string',
'properties' => 'tns:name_value_list',
'add_to_layout' => 'xsd:int',
),
array(
'return' => 'tns:error_value'
),
$NAMESPACE
);
function set_custom_field($session, $module_name, $type, $properties, $add_to_layout) {
global $current_user;
global $beanList, $beanFiles;
global $custom_field_meta;
$error = new SoapError();
$request_arr = array(
'action' => 'SaveField',
'is_update' => 'true',
'module' => 'ModuleBuilder',
'view_module' => $module_name,
'view_package' => 'studio'
);
// ERROR CHECKING
if(!validate_authenticated($session)) {
$error->set_error('invalid_login');
return $error->get_soap_array();
}
if (!is_admin($current_user)) {
$error->set_error('no_admin');
return $error->get_soap_array();
}
if(empty($beanList[$module_name])){
$error->set_error('no_module');
return $error->get_soap_array();
}
if (empty($custom_field_meta[$type])) {
$error->set_error('custom_field_type_not_supported');
return $error->get_soap_array();
}
$new_properties = array();
foreach($properties as $value) {
$new_properties[$value['name']] = $value['value'];
}
foreach ($custom_field_meta[$type] as $property) {
if (!isset($new_properties[$property])) {
$error->set_error('custom_field_property_not_supplied');
return $error->get_soap_array();
}
$request_arr[$property] = $new_properties[$property];
}
// $request_arr should now contain all the necessary information to create a custom field
// merge $request_arr with $_POST/$_REQUEST, where the action_saveField() method expects them
$_REQUEST = array_merge($_REQUEST, $request_arr);
$_POST = array_merge($_POST, $request_arr);
require_once('include/MVC/Controller/SugarController.php');
require_once('modules/ModuleBuilder/controller.php');
require_once('modules/ModuleBuilder/parsers/ParserFactory.php');
$mbc = new ModuleBuilderController();
$mbc->setup();
$mbc->action_SaveField();
// add the field to the given module's EditView and DetailView layouts
if ($add_to_layout == 1) {
$layout_properties = array(
'name' => $new_properties['name'],
'label' => $new_properties['label']
);
if (isset($new_properties['customCode'])) {
$layout_properties['customCode'] = $new_properties['customCode'];
}
if (isset($new_properties['customLabel'])) {
$layout_properties['customLabel'] = $new_properties['customLabel'];
}
// add the field to the DetailView
$parser = ParserFactory::getParser('layoutview', FALSE);
$parser->init($module_name, 'DetailView', FALSE);
$parser->_addField($layout_properties);
$parser->writeWorkingFile();
$parser->handleSave();
unset($parser);
// add the field to the EditView
$parser = ParserFactory::getParser('layoutview', FALSE);
$parser->init($module_name, 'EditView', FALSE);
$parser->_addField($layout_properties);
$parser->writeWorkingFile();
$parser->handleSave();
}
return $error->get_soap_array();
}
?>

1997
soap/SoapSugarUsers.php Executable file

File diff suppressed because it is too large Load Diff

650
soap/SoapTypes.php Executable file
View File

@@ -0,0 +1,650 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
$server->wsdl->addComplexType(
'note_attachment',
'complexType',
'struct',
'all',
'',
array(
"id" => array('name'=>"id",'type'=>'xsd:string'),
"filename" => array('name'=>"filename",'type'=>'xsd:string'),
"file" => array('name'=>"file",'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'return_note_attachment',
'complexType',
'struct',
'all',
'',
array(
"note_attachment"=>array('name'=>'note_attachment', 'type'=>'tns:note_attachment'),
"error"=> array('name'=>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'user_auth',
'complexType',
'struct',
'all',
'',
array(
'user_name'=>array('name'=>'user_name', 'type'=>'xsd:string'),
'password' => array('name'=>'password', 'type'=>'xsd:string'),
'version'=>array('name'=>'version', 'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'field',
'complexType',
'struct',
'all',
'',
array(
'name'=>array('name'=>'name', 'type'=>'xsd:string'),
'type'=>array('name'=>'type', 'type'=>'xsd:string'),
'label'=>array('name'=>'label', 'type'=>'xsd:string'),
'required'=>array('name'=>'required', 'type'=>'xsd:int'),
'options'=>array('name'=>'options', 'type'=>'tns:name_value_list'),
'default_value'=>array('name'=>'name', 'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'field_list',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:field[]')
),
'tns:field'
);
$server->wsdl->addComplexType(
'name_value',
'complexType',
'struct',
'all',
'',
array(
'name'=>array('name'=>'name', 'type'=>'xsd:string'),
'value'=>array('name'=>'value', 'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'name_value_list',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:name_value[]')
),
'tns:name_value'
);
$server->wsdl->addComplexType(
'name_value_lists',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:name_value_list[]')
),
'tns:name_value_list'
);
//these are just a list of fields we want to get
$server->wsdl->addComplexType(
'select_fields',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'xsd:string[]')
),
'xsd:string'
);
//these are just a list of fields we want to get
$server->wsdl->addComplexType(
'module_fields',
'complexType',
'struct',
'all',
'',
array(
'module_name'=>array('name'=>'module_name', 'type'=>'xsd:string'),
'module_fields'=>array('name'=>'module_fields', 'type'=>'tns:field_list'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
// a listing of available modules
$server->wsdl->addComplexType(
'module_list',
'complexType',
'struct',
'all',
'',
array(
'modules'=>array('name'=>'modules', 'type'=>'tns:select_fields'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'error_value',
'complexType',
'struct',
'all',
'',
array(
'number'=>array('name'=>'number', 'type'=>'xsd:string'),
'name'=>array('name'=>'name', 'type'=>'xsd:string'),
'description'=>array('name'=>'description', 'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'entry_value',
'complexType',
'struct',
'all',
'',
array(
'id'=>array('name'=>'id', 'type'=>'xsd:string'),
'module_name'=>array('name'=>'module_name', 'type'=>'xsd:string'),
'name_value_list'=>array('name'=>'name_value_list', 'type'=>'tns:name_value_list'),
)
);
$server->wsdl->addComplexType(
'entry_list',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:entry_value[]')
),
'tns:entry_value'
);
$server->wsdl->addComplexType(
'get_mailmerge_document_result',
'complexType',
'struct',
'all',
'',
array(
'html' => array('name'=>'html', 'type'=>'xsd:string'),
'name_value_list'=>array('name'=>'name_value_list', 'type'=>'tns:name_value_list'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'get_entry_list_result',
'complexType',
'struct',
'all',
'',
array(
'result_count' => array('name'=>'result_count', 'type'=>'xsd:int'),
'next_offset' => array('name'=>'next_offset', 'type'=>'xsd:int'),
'field_list'=>array('name'=>'field_list', 'type'=>'tns:field_list'),
'entry_list' => array('name' =>'entry_list', 'type'=>'tns:entry_list'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'get_entry_result',
'complexType',
'struct',
'all',
'',
array(
'field_list'=>array('name'=>'field_list', 'type'=>'tns:field_list'),
'entry_list' => array('name' =>'entry_list', 'type'=>'tns:entry_list'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'set_entry_result',
'complexType',
'struct',
'all',
'',
array(
'id' => array('name'=>'id', 'type'=>'xsd:string'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'set_entries_result',
'complexType',
'struct',
'all',
'',
array(
'ids' => array('name'=>'ids', 'type'=>'tns:select_fields'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'id_mod',
'complexType',
'struct',
'all',
'',
array(
'id' => array('name'=>'id', 'type'=>'xsd:string'),
'date_modified' => array('name' =>'date_modified', 'type'=>'xsd:string'),
'deleted' => array('name' =>'deleted', 'type'=>'xsd:int'),
)
);
//these are just a list of fields we want to get
$server->wsdl->addComplexType(
'ids_mods',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:id_mod[]')
),
'tns:id_mod'
);
$server->wsdl->addComplexType(
'get_relationships_result',
'complexType',
'struct',
'all',
'',
array(
'ids' => array('name'=>'ids', 'type'=>'tns:ids_mods'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'set_relationship_value',
'complexType',
'struct',
'all',
'',
array(
'module1'=>array('name'=>'module1', 'type'=>'xsd:string'),
'module1_id'=>array('name'=>'module1_id', 'type'=>'xsd:string'),
'module2'=>array('name'=>'module2', 'type'=>'xsd:string'),
'module2_id'=>array('name'=>'module_2_id', 'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'set_relationship_list',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:set_relationship_value[]')
),
'tns:set_relationship_value'
);
$server->wsdl->addComplexType(
'set_relationship_list_result',
'complexType',
'struct',
'all',
'',
array(
'created' => array('name'=>'created', 'type'=>'xsd:int'),
'failed' => array('name'=>'failed', 'type'=>'xsd:int'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'document_revision',
'complexType',
'struct',
'all',
'',
array(
"id" => array('name'=>"id",'type'=>'xsd:string'),
"document_name" => array('name'=>"document_name",'type'=>'xsd:string'),
"revision" => array('name' => "revision", 'type'=>'xsd:string'),
"filename" => array('name' => "filename", 'type'=>'xsd:string'),
"file" => array('name'=>"file",'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'get_entry_list_result_encoded',
'complexType',
'struct',
'all',
'',
array(
'result_count' => array('name'=>'result_count', 'type'=>'xsd:int'),
'next_offset' => array('name'=>'next_offset', 'type'=>'xsd:int'),
'total_count' => array('name'=>'total_count', 'type'=>'xsd:int'),
'field_list' => array('name'=>'field_list', 'type'=>'tns:select_fields'),
'entry_list' => array('name'=>'entry_list', 'type'=>'xsd:string'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'get_sync_result_encoded',
'complexType',
'struct',
'all',
'',
array(
'result' => array('name'=>'result', 'type'=>'xsd:string'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'get_quick_sync_result_encoded',
'complexType',
'struct',
'all',
'',
array(
'result' => array('name'=>'result', 'type'=>'xsd:string'),
'result_count' => array('name'=>'result_count', 'type'=>'xsd:int'),
'next_offset' => array('name'=>'next_offset', 'type'=>'xsd:int'),
'total_count' => array('name'=>'total_count', 'type'=>'xsd:int'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'return_document_revision',
'complexType',
'struct',
'all',
'',
array(
"document_revision"=>array('name'=>'document_revision', 'type'=>'tns:document_revision'),
"error"=> array('name'=>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'name_value_operator',
'complexType',
'struct',
'all',
'',
array(
'name'=>array('name'=>'name', 'type'=>'xsd:string'),
'value'=>array('name'=>'value', 'type'=>'xsd:string'),
'operator'=>array('name'=>'operator', 'type'=>'xsd:string'),
'value_array'=>array('name'=>'value_array', 'type'=>'tns:select_fields')
)
);
$server->wsdl->addComplexType(
'name_value_operator_list',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:name_value_operator[]')
),
'tns:name_value_operator'
);
$server->wsdl->addComplexType(
'newsletter',
'complexType',
'struct',
'all',
'',
array(
'name'=>array('name'=>'name', 'type'=>'xsd:string'),
'prospect_list_id'=>array('name'=>'prospect_list_id', 'type'=>'xsd:string'),
'campaign_id'=>array('name'=>'campaign_id', 'type'=>'xsd:string'),
'description'=>array('name'=>'description', 'type'=>'xsd:string'),
'frequency'=>array('name'=>'frequency', 'type'=>'xsd:string'),
)
);
$server->wsdl->addComplexType(
'newsletter_list',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:newsletter[]')
),
'tns:newsletter'
);
$server->wsdl->addComplexType(
'get_subscription_lists_result',
'complexType',
'struct',
'all',
'',
array(
'unsubscribed' => array('name'=>'unsubscribed', 'type'=>'tns:newsletter_list'),
'subscribed' => array('name'=>'subscribed', 'type'=>'tns:newsletter_list'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
// generic type for an array of strings
$server->wsdl->addComplexType(
'str_array',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array(
'ref' => 'SOAP-ENC:arrayType',
'wsdl:arrayType' => 'xsd:string[]'
)
),
'xsd:string'
);
$server->wsdl->addComplexType(
'name_value_lists_error',
'complexType',
'struct',
'all',
'',
array(
'name_value_lists' => array(
'name' => 'panels',
'type' => 'tns:name_value_lists'
),
'error' => array(
'name' => 'error',
'type' => 'tns:error_value'
)
)
);
$server->wsdl->addComplexType(
'get_entries_count_result',
'complexType',
'struct',
'all',
'',
array(
'result_count'=>array('name'=>'result_count', 'type'=>'xsd:int'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
$server->wsdl->addComplexType(
'set_entries_detail_result',
'complexType',
'struct',
'all',
'',
array(
'name_value_lists' => array('name'=>'name_value_lists', 'type'=>'tns:name_value_lists'),
'error' => array('name' =>'error', 'type'=>'tns:error_value'),
)
);
?>

View File

@@ -0,0 +1,996 @@
<?php
/*
$Id: class.nusoap_base.php,v 1.56 2010/04/26 20:15:08 snichol Exp $
NuSOAP - Web Services Toolkit for PHP
Copyright (c) 2002 NuSphere Corporation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The NuSOAP project home is:
http://sourceforge.net/projects/nusoap/
The primary support for NuSOAP is the Help forum on the project home page.
If you have any questions or comments, please email:
Dietrich Ayala
dietrich@ganx4.com
http://dietrich.ganx4.com/nusoap
NuSphere Corporation
http://www.nusphere.com
*/
/*
* Some of the standards implmented in whole or part by NuSOAP:
*
* SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
* WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
* SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
* XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
* Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
* XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
* RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
* RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
* RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
*/
/* load classes
// necessary classes
require_once('class.soapclient.php');
require_once('class.soap_val.php');
require_once('class.soap_parser.php');
require_once('class.soap_fault.php');
// transport classes
require_once('class.soap_transport_http.php');
// optional add-on classes
require_once('class.xmlschema.php');
require_once('class.wsdl.php');
// server class
require_once('class.soap_server.php');*/
// class variable emulation
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
/**
*
* nusoap_base
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.nusoap_base.php,v 1.56 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_base {
/**
* Identification for HTTP headers.
*
* @var string
* @access private
*/
var $title = 'NuSOAP';
/**
* Version for HTTP headers.
*
* @var string
* @access private
*/
var $version = '0.9.5';
/**
* CVS revision for HTTP headers.
*
* @var string
* @access private
*/
var $revision = '$Revision: 1.56 $';
/**
* Current error string (manipulated by getError/setError)
*
* @var string
* @access private
*/
var $error_str = '';
/**
* Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
*
* @var string
* @access private
*/
var $debug_str = '';
/**
* toggles automatic encoding of special characters as entities
* (should always be true, I think)
*
* @var boolean
* @access private
*/
var $charencoding = true;
/**
* the debug level for this instance
*
* @var integer
* @access private
*/
var $debugLevel;
/**
* set schema version
*
* @var string
* @access public
*/
var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
/**
* charset encoding for outgoing messages
*
* @var string
* @access public
*/
var $soap_defencoding = 'ISO-8859-1';
//var $soap_defencoding = 'UTF-8';
/**
* namespaces in an array of prefix => uri
*
* this is "seeded" by a set of constants, but it may be altered by code
*
* @var array
* @access public
*/
var $namespaces = array(
'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
'xsd' => 'http://www.w3.org/2001/XMLSchema',
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
);
/**
* namespaces used in the current context, e.g. during serialization
*
* @var array
* @access private
*/
var $usedNamespaces = array();
/**
* XML Schema types in an array of uri => (array of xml type => php type)
* is this legacy yet?
* no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
* @var array
* @access public
*/
var $typemap = array(
'http://www.w3.org/2001/XMLSchema' => array(
'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
// abstract "any" types
'anyType'=>'string','anySimpleType'=>'string',
// derived datatypes
'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
'http://www.w3.org/2000/10/XMLSchema' => array(
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
'float'=>'double','dateTime'=>'string',
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
'http://www.w3.org/1999/XMLSchema' => array(
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
'float'=>'double','dateTime'=>'string',
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
'http://xml.apache.org/xml-soap' => array('Map')
);
/**
* XML entities to convert
*
* @var array
* @access public
* @deprecated
* @see expandEntities
*/
var $xmlEntities = array('quot' => '"','amp' => '&',
'lt' => '<','gt' => '>','apos' => "'");
/**
* constructor
*
* @access public
*/
function nusoap_base() {
$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
/**
* gets the global debug level, which applies to future instances
*
* @return integer Debug level 0-9, where 0 turns off
* @access public
*/
function getGlobalDebugLevel() {
return $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
/**
* sets the global debug level, which applies to future instances
*
* @param int $level Debug level 0-9, where 0 turns off
* @access public
*/
function setGlobalDebugLevel($level) {
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
}
/**
* gets the debug level for this instance
*
* @return int Debug level 0-9, where 0 turns off
* @access public
*/
function getDebugLevel() {
return $this->debugLevel;
}
/**
* sets the debug level for this instance
*
* @param int $level Debug level 0-9, where 0 turns off
* @access public
*/
function setDebugLevel($level) {
$this->debugLevel = $level;
}
/**
* adds debug data to the instance debug string with formatting
*
* @param string $string debug data
* @access private
*/
function debug($string){
if ($this->debugLevel > 0) {
$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
}
}
/**
* adds debug data to the instance debug string without formatting
*
* @param string $string debug data
* @access public
*/
function appendDebug($string){
if ($this->debugLevel > 0) {
// it would be nice to use a memory stream here to use
// memory more efficiently
$this->debug_str .= $string;
}
}
/**
* clears the current debug data for this instance
*
* @access public
*/
function clearDebug() {
// it would be nice to use a memory stream here to use
// memory more efficiently
$this->debug_str = '';
}
/**
* gets the current debug data for this instance
*
* @return debug data
* @access public
*/
function &getDebug() {
// it would be nice to use a memory stream here to use
// memory more efficiently
return $this->debug_str;
}
/**
* gets the current debug data for this instance as an XML comment
* this may change the contents of the debug data
*
* @return debug data as an XML comment
* @access public
*/
function &getDebugAsXMLComment() {
// it would be nice to use a memory stream here to use
// memory more efficiently
while (strpos($this->debug_str, '--')) {
$this->debug_str = str_replace('--', '- -', $this->debug_str);
}
$ret = "<!--\n" . $this->debug_str . "\n-->";
return $ret;
}
/**
* expands entities, e.g. changes '<' to '&lt;'.
*
* @param string $val The string in which to expand entities.
* @access private
*/
function expandEntities($val) {
if ($this->charencoding) {
$val = str_replace('&', '&amp;', $val);
$val = str_replace("'", '&apos;', $val);
$val = str_replace('"', '&quot;', $val);
$val = str_replace('<', '&lt;', $val);
$val = str_replace('>', '&gt;', $val);
}
return $val;
}
/**
* returns error string if present
*
* @return mixed error string or false
* @access public
*/
function getError(){
if($this->error_str != ''){
return $this->error_str;
}
return false;
}
/**
* sets error string
*
* @return boolean $string error string
* @access private
*/
function setError($str){
$this->error_str = $str;
}
/**
* detect if array is a simple array or a struct (associative array)
*
* @param mixed $val The PHP array
* @return string (arraySimple|arrayStruct)
* @access private
*/
function isArraySimpleOrStruct($val) {
$keyList = array_keys($val);
foreach ($keyList as $keyListValue) {
if (!is_int($keyListValue)) {
return 'arrayStruct';
}
}
return 'arraySimple';
}
/**
* serializes PHP values in accordance w/ section 5. Type information is
* not serialized if $use == 'literal'.
*
* @param mixed $val The value to serialize
* @param string $name The name (local part) of the XML element
* @param string $type The XML schema type (local part) for the element
* @param string $name_ns The namespace for the name of the XML element
* @param string $type_ns The namespace for the type of the element
* @param array $attributes The attributes to serialize as name=>value pairs
* @param string $use The WSDL "use" (encoded|literal)
* @param boolean $soapval Whether this is called from soapval.
* @return string The serialized element, possibly with child elements
* @access public
*/
function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
$this->appendDebug('value=' . $this->varDump($val));
$this->appendDebug('attributes=' . $this->varDump($attributes));
if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
$this->debug("serialize_val: serialize soapval");
$xml = $val->serialize($use);
$this->appendDebug($val->getDebug());
$val->clearDebug();
$this->debug("serialize_val of soapval returning $xml");
return $xml;
}
// force valid name if necessary
if (is_numeric($name)) {
$name = '__numeric_' . $name;
} elseif (! $name) {
$name = 'noname';
}
// if name has ns, add ns prefix to name
$xmlns = '';
if($name_ns){
$prefix = 'nu'.rand(1000,9999);
$name = $prefix.':'.$name;
$xmlns .= " xmlns:$prefix=\"$name_ns\"";
}
// if type is prefixed, create type prefix
if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
// need to fix this. shouldn't default to xsd if no ns specified
// w/o checking against typemap
$type_prefix = 'xsd';
} elseif($type_ns){
$type_prefix = 'ns'.rand(1000,9999);
$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
}
// serialize attributes if present
$atts = '';
if($attributes){
foreach($attributes as $k => $v){
$atts .= " $k=\"".$this->expandEntities($v).'"';
}
}
// serialize null value
if (is_null($val)) {
$this->debug("serialize_val: serialize null");
if ($use == 'literal') {
// TODO: depends on minOccurs
$xml = "<$name$xmlns$atts/>";
$this->debug("serialize_val returning $xml");
return $xml;
} else {
if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
$xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
$this->debug("serialize_val returning $xml");
return $xml;
}
}
// serialize if an xsd built-in primitive type
if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
$this->debug("serialize_val: serialize xsd built-in primitive 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') {
$xml = "<$name$xmlns$atts>$val</$name>";
$this->debug("serialize_val returning $xml");
return $xml;
} else {
$xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
$this->debug("serialize_val returning $xml");
return $xml;
}
}
// detect type and serialize
$xml = '';
switch(true) {
case (is_bool($val) || $type == 'boolean'):
$this->debug("serialize_val: serialize boolean");
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif (! $val) {
$val = 0;
}
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
}
break;
case (is_int($val) || is_long($val) || $type == 'int'):
$this->debug("serialize_val: serialize int");
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
}
break;
case (is_float($val)|| is_double($val) || $type == 'float'):
$this->debug("serialize_val: serialize float");
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
}
break;
case (is_string($val) || $type == 'string'):
$this->debug("serialize_val: serialize string");
$val = $this->expandEntities($val);
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
}
break;
case is_object($val):
$this->debug("serialize_val: serialize object");
if (get_class($val) == 'soapval') {
$this->debug("serialize_val: serialize soapval object");
$pXml = $val->serialize($use);
$this->appendDebug($val->getDebug());
$val->clearDebug();
} else {
if (! $name) {
$name = get_class($val);
$this->debug("In serialize_val, used class name $name as element name");
} else {
$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
}
foreach(get_object_vars($val) as $k => $v){
$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
}
}
if(isset($type) && isset($type_prefix)){
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$pXml</$name>";
} else {
$xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
}
break;
break;
case (is_array($val) || $type):
// detect if struct or array
$valueType = $this->isArraySimpleOrStruct($val);
if($valueType=='arraySimple' || preg_match('/^ArrayOf/',$type)){
$this->debug("serialize_val: serialize array");
$i = 0;
if(is_array($val) && count($val)> 0){
foreach($val as $v){
if(is_object($v) && get_class($v) == 'soapval'){
$tt_ns = $v->type_ns;
$tt = $v->type;
} elseif (is_array($v)) {
$tt = $this->isArraySimpleOrStruct($v);
} else {
$tt = gettype($v);
}
$array_types[$tt] = 1;
// TODO: for literal, the name should be $name
$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
++$i;
}
if(count($array_types) > 1){
$array_typename = 'xsd:anyType';
} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
if ($tt == 'integer') {
$tt = 'int';
}
$array_typename = 'xsd:'.$tt;
} elseif(isset($tt) && $tt == 'arraySimple'){
$array_typename = 'SOAP-ENC:Array';
} elseif(isset($tt) && $tt == 'arrayStruct'){
$array_typename = 'unnamed_struct_use_soapval';
} else {
// if type is prefixed, create type prefix
if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
$array_typename = 'xsd:' . $tt;
} elseif ($tt_ns) {
$tt_prefix = 'ns' . rand(1000, 9999);
$array_typename = "$tt_prefix:$tt";
$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
} else {
$array_typename = $tt;
}
}
$array_type = $i;
if ($use == 'literal') {
$type_str = '';
} else if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
}
// empty array
} else {
if ($use == 'literal') {
$type_str = '';
} else if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
}
}
// TODO: for array in literal, there is no wrapper here
$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
} else {
// got a struct
$this->debug("serialize_val: serialize struct");
if(isset($type) && isset($type_prefix)){
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>";
} else {
$xml .= "<$name$xmlns$type_str$atts>";
}
foreach($val as $k => $v){
// Apache Map
if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
$xml .= '<item>';
$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
$xml .= '</item>';
} else {
$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
}
}
$xml .= "</$name>";
}
break;
default:
$this->debug("serialize_val: serialize unknown");
$xml .= 'not detected, got '.gettype($val).' for '.$val;
break;
}
$this->debug("serialize_val returning $xml");
return $xml;
}
/**
* serializes a message
*
* @param string $body the XML of the SOAP body
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
* @param array $namespaces optional the namespaces used in generating the body and headers
* @param string $style optional (rpc|document)
* @param string $use optional (encoded|literal)
* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
* @return string the message
* @access public
*/
function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
// TODO: add an option to automatically run utf8_encode on $body and $headers
// if $this->soap_defencoding is UTF-8. Not doing this automatically allows
// one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
$this->debug("headers:");
$this->appendDebug($this->varDump($headers));
$this->debug("namespaces:");
$this->appendDebug($this->varDump($namespaces));
// serialize namespaces
$ns_string = '';
foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
$ns_string .= " xmlns:$k=\"$v\"";
}
if($encodingStyle) {
$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
}
// serialize headers
if($headers){
if (is_array($headers)) {
$xml = '';
foreach ($headers as $k => $v) {
if (is_object($v) && get_class($v) == 'soapval') {
$xml .= $this->serialize_val($v, false, false, false, false, false, $use);
} else {
$xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
}
}
$headers = $xml;
$this->debug("In serializeEnvelope, serialized array of headers to $headers");
}
$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
}
// serialize envelope
return
'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
'<SOAP-ENV:Envelope'.$ns_string.">".
$headers.
"<SOAP-ENV:Body>".
$body.
"</SOAP-ENV:Body>".
"</SOAP-ENV:Envelope>";
}
/**
* formats a string to be inserted into an HTML stream
*
* @param string $str The string to format
* @return string The formatted string
* @access public
* @deprecated
*/
function formatDump($str){
$str = htmlspecialchars($str);
return nl2br($str);
}
/**
* contracts (changes namespace to prefix) a qualified name
*
* @param string $qname qname
* @return string contracted qname
* @access private
*/
function contractQname($qname){
// get element namespace
//$this->xdebug("Contract $qname");
if (strrpos($qname, ':')) {
// get unqualified name
$name = substr($qname, strrpos($qname, ':') + 1);
// get ns
$ns = substr($qname, 0, strrpos($qname, ':'));
$p = $this->getPrefixFromNamespace($ns);
if ($p) {
return $p . ':' . $name;
}
return $qname;
} else {
return $qname;
}
}
/**
* expands (changes prefix to namespace) a qualified name
*
* @param string $qname qname
* @return string expanded qname
* @access private
*/
function expandQname($qname){
// get element prefix
if(strpos($qname,':') && !preg_match('/^http:\/\//',$qname)){
// get unqualified name
$name = substr(strstr($qname,':'),1);
// get ns prefix
$prefix = substr($qname,0,strpos($qname,':'));
if(isset($this->namespaces[$prefix])){
return $this->namespaces[$prefix].':'.$name;
} else {
return $qname;
}
} else {
return $qname;
}
}
/**
* returns the local part of a prefixed string
* returns the original string, if not prefixed
*
* @param string $str The prefixed string
* @return string The local part
* @access public
*/
function getLocalPart($str){
if($sstr = strrchr($str,':')){
// get unqualified name
return substr( $sstr, 1 );
} else {
return $str;
}
}
/**
* returns the prefix part of a prefixed string
* returns false, if not prefixed
*
* @param string $str The prefixed string
* @return mixed The prefix or false if there is no prefix
* @access public
*/
function getPrefix($str){
if($pos = strrpos($str,':')){
// get prefix
return substr($str,0,$pos);
}
return false;
}
/**
* pass it a prefix, it returns a namespace
*
* @param string $prefix The prefix
* @return mixed The namespace, false if no namespace has the specified prefix
* @access public
*/
function getNamespaceFromPrefix($prefix){
if (isset($this->namespaces[$prefix])) {
return $this->namespaces[$prefix];
}
//$this->setError("No namespace registered for prefix '$prefix'");
return false;
}
/**
* returns the prefix for a given namespace (or prefix)
* or false if no prefixes registered for the given namespace
*
* @param string $ns The namespace
* @return mixed The prefix, false if the namespace has no prefixes
* @access public
*/
function getPrefixFromNamespace($ns) {
foreach ($this->namespaces as $p => $n) {
if ($ns == $n || $ns == $p) {
$this->usedNamespaces[$p] = $n;
return $p;
}
}
return false;
}
/**
* returns the time in ODBC canonical form with microseconds
*
* @return string The time in ODBC canonical form with microseconds
* @access public
*/
function getmicrotime() {
if (function_exists('gettimeofday')) {
$tod = gettimeofday();
$sec = $tod['sec'];
$usec = $tod['usec'];
} else {
$sec = time();
$usec = 0;
}
return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
}
/**
* Returns a string with the output of var_dump
*
* @param mixed $data The variable to var_dump
* @return string The output of var_dump
* @access public
*/
function varDump($data) {
ob_start();
var_dump($data);
$ret_val = ob_get_contents();
ob_end_clean();
return $ret_val;
}
/**
* represents the object as a string
*
* @return string
* @access public
*/
function __toString() {
return $this->varDump($this);
}
}
// XML Schema Datatype Helper Functions
//xsd:dateTime helpers
/**
* convert unix timestamp to ISO 8601 compliant date string
*
* @param int $timestamp Unix time stamp
* @param boolean $utc Whether the time stamp is UTC or local
* @return mixed ISO 8601 date string or false
* @access public
*/
function timestamp_to_iso8601($timestamp,$utc=true){
$datestr = date('Y-m-d\TH:i:sO',$timestamp);
$pos = strrpos($datestr, "+");
if ($pos === FALSE) {
$pos = strrpos($datestr, "-");
}
if ($pos !== FALSE) {
if (strlen($datestr) == $pos + 5) {
$datestr = substr($datestr, 0, $pos + 3) . ':' . substr($datestr, -2);
}
}
if($utc){
$pattern = '/'.
'([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(preg_match($pattern,$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
* @return mixed Unix timestamp (int) or false
* @access public
*/
function iso8601_to_timestamp($datestr){
$pattern = '/'.
'([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(preg_match($pattern,$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 gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
// return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
} else {
return false;
}
}
/**
* sleeps some number of microseconds
*
* @param string $usec the number of microseconds to sleep
* @access public
* @deprecated
*/
function usleepWindows($usec)
{
$start = gettimeofday();
do
{
$stop = gettimeofday();
$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
+ $stop['usec'] - $start['usec'];
}
while ($timePassed < $usec);
}
?>

View File

@@ -0,0 +1,90 @@
<?php
/**
* Contains information for a SOAP fault.
* Mainly used for returning faults from deployed functions
* in a server instance.
* @author Dietrich Ayala <dietrich@ganx4.com>
* @version $Id: class.soap_fault.php,v 1.14 2007/04/11 15:49:47 snichol Exp $
* @access public
*/
class nusoap_fault extends nusoap_base {
/**
* The fault code (client|server)
* @var string
* @access private
*/
var $faultcode;
/**
* The fault actor
* @var string
* @access private
*/
var $faultactor;
/**
* The fault string, a description of the fault
* @var string
* @access private
*/
var $faultstring;
/**
* The fault detail, typically a string or array of string
* @var mixed
* @access private
*/
var $faultdetail;
/**
* constructor
*
* @param string $faultcode (SOAP-ENV:Client | SOAP-ENV:Server)
* @param string $faultactor only used when msg routed between multiple actors
* @param string $faultstring human readable error message
* @param mixed $faultdetail detail, typically a string or array of string
*/
function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
parent::nusoap_base();
$this->faultcode = $faultcode;
$this->faultactor = $faultactor;
$this->faultstring = $faultstring;
$this->faultdetail = $faultdetail;
}
/**
* serialize a fault
*
* @return string The serialization of the fault instance.
* @access public
*/
function serialize(){
$ns_string = '';
foreach($this->namespaces as $k => $v){
$ns_string .= "\n xmlns:$k=\"$v\"";
}
$return_msg =
'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
'<SOAP-ENV:Body>'.
'<SOAP-ENV:Fault>'.
$this->serialize_val($this->faultcode, 'faultcode').
$this->serialize_val($this->faultactor, 'faultactor').
$this->serialize_val($this->faultstring, 'faultstring').
$this->serialize_val($this->faultdetail, 'detail').
'</SOAP-ENV:Fault>'.
'</SOAP-ENV:Body>'.
'</SOAP-ENV:Envelope>';
return $return_msg;
}
}
/**
* Backward compatibility
*/
class soap_fault extends nusoap_fault {
}
?>

View File

@@ -0,0 +1,643 @@
<?php
/**
*
* nusoap_parser class parses SOAP XML messages into native PHP values
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.soap_parser.php,v 1.42 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_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; // parsed SOAP Body
var $soapheader = NULL; // parsed SOAP Header
var $responseHeaders = ''; // incoming SOAP headers (text)
var $body_position = 0;
// for multiref parsing:
// array of id => pos
var $ids = array();
// array of id => hrefs => pos
var $multirefs = array();
// toggle for auto-decoding element content
var $decode_utf8 = true;
/**
* constructor that actually does the parsing
*
* @param string $xml SOAP message
* @param string $encoding character encoding scheme of message
* @param string $method method for which XML is parsed (unused?)
* @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
* @access public
*/
function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
parent::nusoap_base();
$this->xml = $xml;
$this->xml_encoding = $encoding;
$this->method = $method;
$this->decode_utf8 = $decode_utf8;
// Check whether content has been read.
if(!empty($xml)){
// Check XML encoding
$pos_xml = strpos($xml, '<?xml');
if ($pos_xml !== FALSE) {
$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
$xml_encoding = $res[1];
if (strtoupper($xml_encoding) != $encoding) {
$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
$this->debug($err);
if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
$this->setError($err);
return;
}
// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
} else {
$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
}
} else {
$this->debug('No encoding specified in XML declaration');
}
} else {
$this->debug('No XML declaration');
}
$this->debug('Entering nusoap_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('in nusoap_parser ctor, message:');
$this->appendDebug($this->varDump($this->message));
$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
if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
$this->soapheader = $this->message[$this->root_header]['result'];
}
// resolve hrefs/ids
if(sizeof($this->multirefs) > 0){
foreach($this->multirefs as $id => $hrefs){
$this->debug('resolving multirefs for id: '.$id);
$idVal = $this->buildVal($this->ids[$id]);
if (is_array($idVal) && isset($idVal['!id'])) {
unset($idVal['!id']);
}
foreach($hrefs as $refPos => $ref){
$this->debug('resolving href at pos '.$refPos);
$this->multirefs[$id][$refPos] = $idVal;
}
}
}
}
xml_parser_free($this->parser);
} else {
$this->debug('xml was empty, didn\'t parse!');
$this->setError('xml was empty, didn\'t parse!');
}
}
/**
* start-element handler
*
* @param resource $parser XML parser object
* @param string $name element name
* @param array $attrs associative array of attributes
* @access private
*/
function start_element($parser, $name, $attrs) {
// position in a total number of elements, starting from 0
// update class level pos
$pos = $this->position++;
// and set mine
$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
// depth = how many levels removed from root?
// set mine as current global depth and increment global depth value
$this->message[$pos]['depth'] = $this->depth++;
// else add self as child to whoever the current parent is
if($pos != 0){
$this->message[$this->parent]['children'] .= '|'.$pos;
}
// set my parent
$this->message[$pos]['parent'] = $this->parent;
// set self as current parent
$this->parent = $pos;
// set self as current value for this depth
$this->depth_array[$this->depth] = $pos;
// get element prefix
if(strpos($name,':')){
// get ns prefix
$prefix = substr($name,0,strpos($name,':'));
// get unqualified name
$name = substr(strstr($name,':'),1);
}
// set status
if ($name == 'Envelope' && $this->status == '') {
$this->status = 'envelope';
} elseif ($name == 'Header' && $this->status == 'envelope') {
$this->root_header = $pos;
$this->status = 'header';
} elseif ($name == 'Body' && $this->status == 'envelope'){
$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(preg_match('/^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'){
if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
// do nothing: already processed arrayType
} else {
$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(preg_match($expr,$value,$regs)){
$this->message[$pos]['typePrefix'] = $regs[1];
$this->message[$pos]['arrayTypePrefix'] = $regs[1];
if (isset($this->namespaces[$regs[1]])) {
$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
} else if (isset($attrs['xmlns:'.$regs[1]])) {
$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
}
$this->message[$pos]['arrayType'] = $regs[2];
$this->message[$pos]['arraySize'] = $regs[3];
$this->message[$pos]['arrayCols'] = $regs[4];
}
// specifies nil value (or not)
} elseif ($key_localpart == 'nil'){
$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
// some other attribute
} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
$this->message[$pos]['xattrs']['!' . $key] = $value;
}
if ($key == 'xmlns') {
$this->default_namespace = $value;
}
// log id
if($key == 'id'){
$this->ids[$value] = $pos;
}
// root
if($key_localpart == 'root' && $value == 1){
$this->status = 'method';
$this->root_struct_name = $name;
$this->root_struct = $pos;
$this->debug("found root struct $this->root_struct_name, pos $pos");
}
// for doclit
$attstr .= " $key=\"$value\"";
}
// get namespace - must be done after namespace atts are processed
if(isset($prefix)){
$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
$this->default_namespace = $this->namespaces[$prefix];
} else {
$this->message[$pos]['namespace'] = $this->default_namespace;
}
if($this->status == 'header'){
if ($this->root_header != $pos) {
$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
}
} elseif($this->root_struct_name != ''){
$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
}
}
/**
* end-element handler
*
* @param resource $parser XML parser object
* @param string $name element name
* @access private
*/
function end_element($parser, $name) {
// position of current element is equal to the last value left in depth_array for my depth
$pos = $this->depth_array[$this->depth--];
// get element prefix
if(strpos($name,':')){
// get ns prefix
$prefix = substr($name,0,strpos($name,':'));
// get unqualified name
$name = substr(strstr($name,':'),1);
}
// build to native type
if(isset($this->body_position) && $pos > $this->body_position){
// deal w/ multirefs
if(isset($this->message[$pos]['attrs']['href'])){
// get id
$id = substr($this->message[$pos]['attrs']['href'],1);
// add placeholder to href array
$this->multirefs[$id][$pos] = 'placeholder';
// add set a reference to it as the result value
$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
// build complexType values
} elseif($this->message[$pos]['children'] != ''){
// if result has already been generated (struct/array)
if(!isset($this->message[$pos]['result'])){
$this->message[$pos]['result'] = $this->buildVal($pos);
}
// build complexType values of attributes and possibly simpleContent
} elseif (isset($this->message[$pos]['xattrs'])) {
if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
$this->message[$pos]['xattrs']['!'] = null;
} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
if (isset($this->message[$pos]['type'])) {
$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
} else {
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
} else {
$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
}
}
}
$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
// set value of simpleType (or nil complexType)
} else {
//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
$this->message[$pos]['xattrs']['!'] = null;
} elseif (isset($this->message[$pos]['type'])) {
$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
} else {
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
} else {
$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
}
}
/* add value to parent's result, if parent is struct/array
$parent = $this->message[$pos]['parent'];
if($this->message[$parent]['type'] != 'map'){
if(strtolower($this->message[$parent]['type']) == 'array'){
$this->message[$parent]['result'][] = $this->message[$pos]['result'];
} else {
$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
}
}
*/
}
}
// for doclit
if($this->status == 'header'){
if ($this->root_header != $pos) {
$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
}
} elseif($pos >= $this->root_struct){
$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
}
// switch status
if ($pos == $this->root_struct){
$this->status = 'body';
$this->root_struct_namespace = $this->message[$pos]['namespace'];
} elseif ($pos == $this->root_header) {
$this->status = 'envelope';
} elseif ($name == 'Body' && $this->status == 'body') {
$this->status = 'envelope';
} elseif ($name == 'Header' && $this->status == 'header') { // will never happen
$this->status = 'envelope';
} elseif ($name == 'Envelope' && $this->status == 'envelope') {
$this->status = '';
}
// set parent back to my parent
$this->parent = $this->message[$pos]['parent'];
}
/**
* element content handler
*
* @param resource $parser XML parser object
* @param string $data element content
* @access private
*/
function character_data($parser, $data){
$pos = $this->depth_array[$this->depth];
if ($this->xml_encoding=='UTF-8'){
// TODO: add an option to disable this for folks who want
// raw UTF-8 that, e.g., might not map to iso-8859-1
// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
if($this->decode_utf8){
$data = utf8_decode($data);
}
}
$this->message[$pos]['cdata'] .= $data;
// for doclit
if($this->status == 'header'){
$this->responseHeaders .= $data;
} else {
$this->document .= $data;
}
}
/**
* get the parsed message (SOAP Body)
*
* @return mixed
* @access public
* @deprecated use get_soapbody instead
*/
function get_response(){
return $this->soapresponse;
}
/**
* get the parsed SOAP Body (NULL if there was none)
*
* @return mixed
* @access public
*/
function get_soapbody(){
return $this->soapresponse;
}
/**
* get the parsed SOAP Header (NULL if there was none)
*
* @return mixed
* @access public
*/
function get_soapheader(){
return $this->soapheader;
}
/**
* get the unparsed SOAP Header
*
* @return string XML or empty if no Header
* @access public
*/
function getHeaders(){
return $this->responseHeaders;
}
/**
* decodes simple types into PHP variables
*
* @param string $value value to decode
* @param string $type XML type to decode
* @param string $typens XML type namespace to decode
* @return mixed PHP value
* @access private
*/
function decodeSimple($value, $type, $typens) {
// TODO: use the namespace!
if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
return (string) $value;
}
if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
return (int) $value;
}
if ($type == 'float' || $type == 'double' || $type == 'decimal') {
return (double) $value;
}
if ($type == 'boolean') {
if (strtolower($value) == 'false' || strtolower($value) == 'f') {
return false;
}
return (boolean) $value;
}
if ($type == 'base64' || $type == 'base64Binary') {
$this->debug('Decode base64 value');
return base64_decode($value);
}
// obscure numeric types
if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
|| $type == 'unsignedInt'
|| $type == 'unsignedShort' || $type == 'unsignedByte') {
return (int) $value;
}
// bogus: parser treats array with no elements as a simple type
if ($type == 'array') {
return array();
}
// everything else
return (string) $value;
}
/**
* builds response structures for compound values (arrays/structs)
* and scalars
*
* @param integer $pos position in node tree
* @return mixed PHP value
* @access private
*/
function buildVal($pos){
if(!isset($this->message[$pos]['type'])){
$this->message[$pos]['type'] = '';
}
$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
// if there are children...
if($this->message[$pos]['children'] != ''){
$this->debug('in buildVal, there are children');
$children = explode('|',$this->message[$pos]['children']);
array_shift($children); // knock off empty
// md array
if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
$r=0; // rowcount
$c=0; // colcount
foreach($children as $child_pos){
$this->debug("in buildVal, got an MD array element: $r, $c");
$params[$r][] = $this->message[$child_pos]['result'];
$c++;
if($c == $this->message[$pos]['arrayCols']){
$c = 0;
$r++;
}
}
// array
} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
$this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
foreach($children as $child_pos){
$params[] = &$this->message[$child_pos]['result'];
}
// apache Map type: java hashtable
} elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
$this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
foreach($children as $child_pos){
$kv = explode("|",$this->message[$child_pos]['children']);
$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
}
// generic compound type
//} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
} else {
// Apache Vector type: treat as an array
$this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
$notstruct = 1;
} else {
$notstruct = 0;
}
//
foreach($children as $child_pos){
if($notstruct){
$params[] = &$this->message[$child_pos]['result'];
} else {
if (isset($params[$this->message[$child_pos]['name']])) {
// de-serialize repeated element name into an array
if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
}
$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
} else {
$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
}
}
}
}
if (isset($this->message[$pos]['xattrs'])) {
$this->debug('in buildVal, handling attributes');
foreach ($this->message[$pos]['xattrs'] as $n => $v) {
$params[$n] = $v;
}
}
// handle simpleContent
if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
$this->debug('in buildVal, handling simpleContent');
if (isset($this->message[$pos]['type'])) {
$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
} else {
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
} else {
$params['!'] = $this->message[$pos]['cdata'];
}
}
}
$ret = is_array($params) ? $params : array();
$this->debug('in buildVal, return:');
$this->appendDebug($this->varDump($ret));
return $ret;
} else {
$this->debug('in buildVal, no children, building scalar');
$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
if (isset($this->message[$pos]['type'])) {
$ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
$this->debug("in buildVal, return: $ret");
return $ret;
}
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
$this->debug("in buildVal, return: $ret");
return $ret;
}
$ret = $this->message[$pos]['cdata'];
$this->debug("in buildVal, return: $ret");
return $ret;
}
}
}
/**
* Backward compatibility
*/
class soap_parser extends nusoap_parser {
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
<?php
/**
* For creating serializable abstractions of native PHP types. This class
* allows element name/namespace, XSD type, and XML attributes to be
* associated with a value. This is extremely useful when WSDL is not
* used, but is also useful when WSDL is used with polymorphic types, including
* xsd:anyType and user-defined types.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @version $Id: class.soap_val.php,v 1.11 2007/04/06 13:56:32 snichol Exp $
* @access public
*/
class soapval extends nusoap_base {
/**
* The XML element name
*
* @var string
* @access private
*/
var $name;
/**
* The XML type name (string or false)
*
* @var mixed
* @access private
*/
var $type;
/**
* The PHP value
*
* @var mixed
* @access private
*/
var $value;
/**
* The XML element namespace (string or false)
*
* @var mixed
* @access private
*/
var $element_ns;
/**
* The XML type namespace (string or false)
*
* @var mixed
* @access private
*/
var $type_ns;
/**
* The XML element attributes (array or false)
*
* @var mixed
* @access private
*/
var $attributes;
/**
* constructor
*
* @param string $name optional name
* @param mixed $type optional type name
* @param mixed $value optional value
* @param mixed $element_ns optional namespace of value
* @param mixed $type_ns optional namespace of type
* @param mixed $attributes associative array of attributes to add to element serialization
* @access public
*/
function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
parent::nusoap_base();
$this->name = $name;
$this->type = $type;
$this->value = $value;
$this->element_ns = $element_ns;
$this->type_ns = $type_ns;
$this->attributes = $attributes;
}
/**
* return serialized value
*
* @param string $use The WSDL use value (encoded|literal)
* @return string XML data
* @access public
*/
function serialize($use='encoded') {
return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
}
/**
* decodes a soapval object into a PHP native type
*
* @return mixed
* @access public
*/
function decode(){
return $this->value;
}
}
?>

View File

@@ -0,0 +1,991 @@
<?php
/**
*
* [nu]soapclient higher level class for easy usage.
*
* usage:
*
* // instantiate client with server info
* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
*
* // call method, get results
* echo $soapclient->call( string methodname [ ,array parameters] );
*
* // bye bye client
* unset($soapclient);
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.soapclient.php,v 1.69 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_client extends nusoap_base {
var $username = ''; // Username for HTTP authentication
var $password = ''; // Password for HTTP authentication
var $authtype = ''; // Type of HTTP authentication
var $certRequest = array(); // Certificate for HTTP SSL authentication
var $requestHeaders = false; // SOAP headers in request (text)
var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
var $responseHeader = NULL; // SOAP Header from response (parsed)
var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
var $endpoint;
var $forceEndpoint = ''; // overrides WSDL endpoint
var $proxyhost = '';
var $proxyport = '';
var $proxyusername = '';
var $proxypassword = '';
var $portName = ''; // port name to use in WSDL
var $xml_encoding = ''; // character set encoding of incoming (response) messages
var $http_encoding = false;
var $timeout = 0; // HTTP connection timeout
var $response_timeout = 30; // HTTP response timeout
var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
var $persistentConnection = false;
var $defaultRpcParams = false; // This is no longer used
var $request = ''; // HTTP request
var $response = ''; // HTTP response
var $responseData = ''; // SOAP payload of response
var $cookies = array(); // Cookies from response or for request
var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
var $operations = array(); // WSDL operations, empty for WSDL initialization error
var $curl_options = array(); // User-specified cURL options
var $bindingType = ''; // WSDL operation binding type
var $use_curl = false; // whether to always try to use cURL
/*
* fault related variables
*/
/**
* @var fault
* @access public
*/
var $fault;
/**
* @var faultcode
* @access public
*/
var $faultcode;
/**
* @var faultstring
* @access public
*/
var $faultstring;
/**
* @var faultdetail
* @access public
*/
var $faultdetail;
/**
* constructor
*
* @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
* @param mixed $wsdl optional, set to 'wsdl' or true if using WSDL
* @param string $proxyhost optional
* @param string $proxyport optional
* @param string $proxyusername optional
* @param string $proxypassword optional
* @param integer $timeout set the connection timeout
* @param integer $response_timeout set the response timeout
* @param string $portName optional portName in WSDL document
* @access public
*/
function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $portName = ''){
parent::nusoap_base();
$this->endpoint = $endpoint;
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
$this->proxyusername = $proxyusername;
$this->proxypassword = $proxypassword;
$this->timeout = $timeout;
$this->response_timeout = $response_timeout;
$this->portName = $portName;
$this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
$this->appendDebug('endpoint=' . $this->varDump($endpoint));
// make values
if($wsdl){
if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
$this->wsdl = $endpoint;
$this->endpoint = $this->wsdl->wsdl;
$this->wsdlFile = $this->endpoint;
$this->debug('existing wsdl instance created from ' . $this->endpoint);
$this->checkWSDL();
} else {
$this->wsdlFile = $this->endpoint;
$this->wsdl = null;
$this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
}
$this->endpointType = 'wsdl';
} else {
$this->debug("instantiate SOAP with endpoint at $endpoint");
$this->endpointType = 'soap';
}
}
/**
* calls method, returns PHP native type
*
* @param string $operation SOAP server URL or path
* @param mixed $params An array, associative or simple, of the parameters
* for the method call, or a string that is the XML
* for the call. For rpc style, this call will
* wrap the XML in a tag named after the method, as
* well as the SOAP Envelope and Body. For document
* style, this will only wrap with the Envelope and Body.
* IMPORTANT: when using an array with document style,
* in which case there
* is really one parameter, the root of the fragment
* used in the call, which encloses what programmers
* normally think of parameters. A parameter array
* *must* include the wrapper.
* @param string $namespace optional method namespace (WSDL can override)
* @param string $soapAction optional SOAPAction value (WSDL can override)
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
* @param boolean $rpcParams optional (no longer used)
* @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
* @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override)
* @return mixed response from SOAP call, normally an associative array mirroring the structure of the XML response, false for certain fatal errors
* @access public
*/
function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
$this->operation = $operation;
$this->fault = false;
$this->setError('');
$this->request = '';
$this->response = '';
$this->responseData = '';
$this->faultstring = '';
$this->faultcode = '';
$this->opData = array();
$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
$this->appendDebug('params=' . $this->varDump($params));
$this->appendDebug('headers=' . $this->varDump($headers));
if ($headers) {
$this->requestHeaders = $headers;
}
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
$this->loadWSDL();
if ($this->getError())
return false;
}
// serialize parameters
if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
// use WSDL for operation
$this->opData = $opData;
$this->debug("found operation");
$this->appendDebug('opData=' . $this->varDump($opData));
if (isset($opData['soapAction'])) {
$soapAction = $opData['soapAction'];
}
if (! $this->forceEndpoint) {
$this->endpoint = $opData['endpoint'];
} else {
$this->endpoint = $this->forceEndpoint;
}
$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
$style = $opData['style'];
$use = $opData['input']['use'];
// add ns to ns array
if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
$nsPrefix = 'ns' . rand(1000, 9999);
$this->wsdl->namespaces[$nsPrefix] = $namespace;
}
$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
// serialize payload
if (is_string($params)) {
$this->debug("serializing param string for WSDL operation $operation");
$payload = $params;
} elseif (is_array($params)) {
$this->debug("serializing param array for WSDL operation $operation");
$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
} else {
$this->debug('params must be array or string');
$this->setError('params must be array or string');
return false;
}
$usedNamespaces = $this->wsdl->usedNamespaces;
if (isset($opData['input']['encodingStyle'])) {
$encodingStyle = $opData['input']['encodingStyle'];
} else {
$encodingStyle = '';
}
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
if ($errstr = $this->wsdl->getError()) {
$this->debug('got wsdl error: '.$errstr);
$this->setError('wsdl error: '.$errstr);
return false;
}
} elseif($this->endpointType == 'wsdl') {
// operation not in WSDL
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->setError('operation '.$operation.' not present in WSDL.');
$this->debug("operation '$operation' not present in WSDL.");
return false;
} else {
// no WSDL
//$this->namespaces['ns1'] = $namespace;
$nsPrefix = 'ns' . rand(1000, 9999);
// serialize
$payload = '';
if (is_string($params)) {
$this->debug("serializing param string for operation $operation");
$payload = $params;
} elseif (is_array($params)) {
$this->debug("serializing param array for operation $operation");
foreach($params as $k => $v){
$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
}
} else {
$this->debug('params must be array or string');
$this->setError('params must be array or string');
return false;
}
$usedNamespaces = array();
if ($use == 'encoded') {
$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
} else {
$encodingStyle = '';
}
}
// wrap RPC calls with method element
if ($style == 'rpc') {
if ($use == 'literal') {
$this->debug("wrapping RPC request with literal method element");
if ($namespace) {
// http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
$payload .
"</$nsPrefix:$operation>";
} else {
$payload = "<$operation>" . $payload . "</$operation>";
}
} else {
$this->debug("wrapping RPC request with encoded method element");
if ($namespace) {
$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
$payload .
"</$nsPrefix:$operation>";
} else {
$payload = "<$operation>" .
$payload .
"</$operation>";
}
}
}
// serialize envelope
$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
// send
$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
if($errstr = $this->getError()){
$this->debug('Error: '.$errstr);
return false;
} else {
$this->return = $return;
$this->debug('sent message successfully and got a(n) '.gettype($return));
$this->appendDebug('return=' . $this->varDump($return));
// fault?
if(is_array($return) && isset($return['faultcode'])){
$this->debug('got fault');
$this->setError($return['faultcode'].': '.$return['faultstring']);
$this->fault = true;
foreach($return as $k => $v){
$this->$k = $v;
$this->debug("$k = $v<br>");
}
return $return;
} elseif ($style == 'document') {
// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
// we are only going to return the first part here...sorry about that
return $return;
} else {
// array of return values
if(is_array($return)){
// multiple 'out' parameters, which we return wrapped up
// in the array
if(sizeof($return) > 1){
return $return;
}
// single 'out' parameter (normally the return value)
$return = array_shift($return);
$this->debug('return shifted value: ');
$this->appendDebug($this->varDump($return));
return $return;
// nothing returned (ie, echoVoid)
} else {
return "";
}
}
}
}
/**
* check WSDL passed as an instance or pulled from an endpoint
*
* @access private
*/
function checkWSDL() {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->debug('checkWSDL');
// catch errors
if ($errstr = $this->wsdl->getError()) {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->debug('got wsdl error: '.$errstr);
$this->setError('wsdl error: '.$errstr);
} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap')) {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->bindingType = 'soap';
$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap12')) {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->bindingType = 'soap12';
$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
$this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
} else {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->debug('getOperations returned false');
$this->setError('no operations defined in the WSDL document!');
}
}
/**
* instantiate wsdl object and parse wsdl file
*
* @access public
*/
function loadWSDL() {
$this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
$this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
$this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
$this->wsdl->fetchWSDL($this->wsdlFile);
$this->checkWSDL();
}
/**
* 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 ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
$this->loadWSDL();
if ($this->getError())
return false;
}
if(isset($this->operations[$operation])){
return $this->operations[$operation];
}
$this->debug("No data for operation: $operation");
}
/**
* send the SOAP message
*
* Note: if the operation has multiple return values
* the return value of this method will be an array
* of those values.
*
* @param string $msg a SOAPx4 soapmsg object
* @param string $soapaction SOAPAction value
* @param integer $timeout set connection timeout in seconds
* @param integer $response_timeout set response timeout in seconds
* @return mixed native PHP types.
* @access private
*/
function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
$this->checkCookies();
// detect transport
switch(true){
// http(s)
case preg_match('/^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, $this->curl_options, $this->use_curl);
if ($this->persistentConnection) {
$http->usePersistentConnection();
}
}
$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
$http->setSOAPAction($soapaction);
if($this->proxyhost && $this->proxyport){
$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
}
if($this->authtype != '') {
$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
}
if($this->http_encoding != ''){
$http->setEncoding($this->http_encoding);
}
$this->debug('sending message, length='.strlen($msg));
if(preg_match('/^http:/',$this->endpoint)){
//if(strpos($this->endpoint,'http:')){
$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
} elseif(preg_match('/^https/',$this->endpoint)){
//} elseif(strpos($this->endpoint,'https:')){
//if(phpversion() == '4.3.0-dev'){
//$response = $http->send($msg,$timeout,$response_timeout);
//$this->request = $http->outgoing_payload;
//$this->response = $http->incoming_payload;
//} else
$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
} else {
$this->setError('no http/s in endpoint url');
}
$this->request = $http->outgoing_payload;
$this->response = $http->incoming_payload;
$this->appendDebug($http->getDebug());
$this->UpdateCookies($http->incoming_cookies);
// save transport object if using persistent connections
if ($this->persistentConnection) {
$http->clearDebug();
if (!is_object($this->persistentConnection)) {
$this->persistentConnection = $http;
}
}
if($err = $http->getError()){
$this->setError('HTTP Error: '.$err);
return false;
} elseif($this->getError()){
return false;
} else {
$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
return $this->parseResponse($http->incoming_headers, $this->responseData);
}
break;
default:
$this->setError('no transport found, or selected transport is not yet supported!');
return false;
break;
}
}
/**
* processes SOAP message returned from server
*
* @param array $headers The HTTP headers
* @param string $data unprocessed response data from server
* @return mixed value of the message, decoded into a PHP type
* @access private
*/
function parseResponse($headers, $data) {
$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
$this->appendDebug($this->varDump($headers));
if (!isset($headers['content-type'])) {
$this->setError('Response not of type text/xml (no content-type header)');
return false;
}
if (!strstr($headers['content-type'], 'text/xml')) {
$this->setError('Response not of type text/xml: ' . $headers['content-type']);
return false;
}
if (strpos($headers['content-type'], '=')) {
$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
$this->debug('Got response encoding: ' . $enc);
if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
$this->xml_encoding = strtoupper($enc);
} else {
$this->xml_encoding = 'US-ASCII';
}
} else {
// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
$this->xml_encoding = 'ISO-8859-1';
}
$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
$parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
// add parser debug data to our debug
$this->appendDebug($parser->getDebug());
// if parse errors
if($errstr = $parser->getError()){
$this->setError( $errstr);
// destroy the parser object
unset($parser);
return false;
} else {
// get SOAP headers
$this->responseHeaders = $parser->getHeaders();
// get SOAP headers
$this->responseHeader = $parser->get_soapheader();
// get decoded message
$return = $parser->get_soapbody();
// add document for doclit support
$this->document = $parser->document;
// destroy the parser object
unset($parser);
// return decode message
return $return;
}
}
/**
* sets user-specified cURL options
*
* @param mixed $option The cURL option (always integer?)
* @param mixed $value The cURL option value
* @access public
*/
function setCurlOption($option, $value) {
$this->debug("setCurlOption option=$option, value=");
$this->appendDebug($this->varDump($value));
$this->curl_options[$option] = $value;
}
/**
* sets the SOAP endpoint, which can override WSDL
*
* @param string $endpoint The endpoint URL to use, or empty string or false to prevent override
* @access public
*/
function setEndpoint($endpoint) {
$this->debug("setEndpoint(\"$endpoint\")");
$this->forceEndpoint = $endpoint;
}
/**
* set the SOAP headers
*
* @param mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
* @access public
*/
function setHeaders($headers){
$this->debug("setHeaders headers=");
$this->appendDebug($this->varDump($headers));
$this->requestHeaders = $headers;
}
/**
* get the SOAP response headers (namespace resolution incomplete)
*
* @return string
* @access public
*/
function getHeaders(){
return $this->responseHeaders;
}
/**
* get the SOAP response Header (parsed)
*
* @return mixed
* @access public
*/
function getHeader(){
return $this->responseHeader;
}
/**
* set proxy info here
*
* @param string $proxyhost
* @param string $proxyport
* @param string $proxyusername
* @param string $proxypassword
* @access public
*/
function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
$this->proxyusername = $proxyusername;
$this->proxypassword = $proxypassword;
}
/**
* if authenticating, set user credentials here
*
* @param string $username
* @param string $password
* @param string $authtype (basic|digest|certificate|ntlm)
* @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
* @access public
*/
function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
$this->debug("setCredentials username=$username authtype=$authtype certRequest=");
$this->appendDebug($this->varDump($certRequest));
$this->username = $username;
$this->password = $password;
$this->authtype = $authtype;
$this->certRequest = $certRequest;
}
/**
* use HTTP encoding
*
* @param string $enc HTTP encoding
* @access public
*/
function setHTTPEncoding($enc='gzip, deflate'){
$this->debug("setHTTPEncoding(\"$enc\")");
$this->http_encoding = $enc;
}
/**
* Set whether to try to use cURL connections if possible
*
* @param boolean $use Whether to try to use cURL
* @access public
*/
function setUseCURL($use) {
$this->debug("setUseCURL($use)");
$this->use_curl = $use;
}
/**
* use HTTP persistent connections if possible
*
* @access public
*/
function useHTTPPersistentConnection(){
$this->debug("useHTTPPersistentConnection");
$this->persistentConnection = true;
}
/**
* gets the default RPC parameter setting.
* If true, default is that call params are like RPC even for document style.
* Each call() can override this value.
*
* This is no longer used.
*
* @return boolean
* @access public
* @deprecated
*/
function getDefaultRpcParams() {
return $this->defaultRpcParams;
}
/**
* sets the default RPC parameter setting.
* If true, default is that call params are like RPC even for document style
* Each call() can override this value.
*
* This is no longer used.
*
* @param boolean $rpcParams
* @access public
* @deprecated
*/
function setDefaultRpcParams($rpcParams) {
$this->defaultRpcParams = $rpcParams;
}
/**
* dynamically creates an instance of a proxy class,
* allowing user to directly call methods from wsdl
*
* @return object soap_proxy object
* @access public
*/
function getProxy() {
$r = rand();
$evalStr = $this->_getProxyClassCode($r);
//$this->debug("proxy class: $evalStr");
if ($this->getError()) {
$this->debug("Error from _getProxyClassCode, so return NULL");
return null;
}
// eval the class
eval($evalStr);
// instantiate proxy object
eval("\$proxy = new nusoap_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->soap_defencoding = $this->soap_defencoding;
$proxy->username = $this->username;
$proxy->password = $this->password;
$proxy->authtype = $this->authtype;
$proxy->certRequest = $this->certRequest;
$proxy->requestHeaders = $this->requestHeaders;
$proxy->endpoint = $this->endpoint;
$proxy->forceEndpoint = $this->forceEndpoint;
$proxy->proxyhost = $this->proxyhost;
$proxy->proxyport = $this->proxyport;
$proxy->proxyusername = $this->proxyusername;
$proxy->proxypassword = $this->proxypassword;
$proxy->http_encoding = $this->http_encoding;
$proxy->timeout = $this->timeout;
$proxy->response_timeout = $this->response_timeout;
$proxy->persistentConnection = &$this->persistentConnection;
$proxy->decode_utf8 = $this->decode_utf8;
$proxy->curl_options = $this->curl_options;
$proxy->bindingType = $this->bindingType;
$proxy->use_curl = $this->use_curl;
return $proxy;
}
/**
* dynamically creates proxy class code
*
* @return string PHP/NuSOAP code for the proxy class
* @access private
*/
function _getProxyClassCode($r) {
$this->debug("in getProxy endpointType=$this->endpointType");
$this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
if ($this->endpointType != 'wsdl') {
$evalStr = 'A proxy can only be created for a WSDL client';
$this->setError($evalStr);
$evalStr = "echo \"$evalStr\";";
return $evalStr;
}
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
$this->loadWSDL();
if ($this->getError()) {
return "echo \"" . $this->getError() . "\";";
}
}
$evalStr = '';
foreach ($this->operations as $operation => $opData) {
if ($operation != '') {
// create param string and param comment string
if (sizeof($opData['input']['parts']) > 0) {
$paramStr = '';
$paramArrayStr = '';
$paramCommentStr = '';
foreach ($opData['input']['parts'] as $name => $type) {
$paramStr .= "\$$name, ";
$paramArrayStr .= "'$name' => \$$name, ";
$paramCommentStr .= "$type \$$name, ";
}
$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
} else {
$paramStr = '';
$paramArrayStr = '';
$paramCommentStr = 'void';
}
$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
$evalStr .= "// $paramCommentStr
function " . str_replace('.', '__', $operation) . "($paramStr) {
\$params = array($paramArrayStr);
return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
}
";
unset($paramStr);
unset($paramCommentStr);
}
}
$evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
'.$evalStr.'
}';
return $evalStr;
}
/**
* dynamically creates proxy class code
*
* @return string PHP/NuSOAP code for the proxy class
* @access public
*/
function getProxyClassCode() {
$r = rand();
return $this->_getProxyClassCode($r);
}
/**
* gets the HTTP body for the current request.
*
* @param string $soapmsg The SOAP payload
* @return string The HTTP body, which includes the SOAP payload
* @access private
*/
function getHTTPBody($soapmsg) {
return $soapmsg;
}
/**
* gets the HTTP content type for the current request.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type for the current request.
* @access private
*/
function getHTTPContentType() {
return 'text/xml';
}
/**
* gets the HTTP content type charset for the current request.
* returns false for non-text content types.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type charset for the current request.
* @access private
*/
function getHTTPContentTypeCharset() {
return $this->soap_defencoding;
}
/*
* whether or not parser should decode utf8 element content
*
* @return always returns true
* @access public
*/
function decodeUTF8($bool){
$this->decode_utf8 = $bool;
return true;
}
/**
* adds a new Cookie into $this->cookies array
*
* @param string $name Cookie Name
* @param string $value Cookie Value
* @return boolean if cookie-set was successful returns true, else false
* @access public
*/
function setCookie($name, $value) {
if (strlen($name) == 0) {
return false;
}
$this->cookies[] = array('name' => $name, 'value' => $value);
return true;
}
/**
* gets all Cookies
*
* @return array with all internal cookies
* @access public
*/
function getCookies() {
return $this->cookies;
}
/**
* checks all Cookies and delete those which are expired
*
* @return boolean always return true
* @access private
*/
function checkCookies() {
if (sizeof($this->cookies) == 0) {
return true;
}
$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
$curr_cookies = $this->cookies;
$this->cookies = array();
foreach ($curr_cookies as $cookie) {
if (! is_array($cookie)) {
$this->debug('Remove cookie that is not an array');
continue;
}
if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
if (strtotime($cookie['expires']) > time()) {
$this->cookies[] = $cookie;
} else {
$this->debug('Remove expired cookie ' . $cookie['name']);
}
} else {
$this->cookies[] = $cookie;
}
}
$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
return true;
}
/**
* updates the current cookies with a new set
*
* @param array $cookies new cookies with which to update current ones
* @return boolean always return true
* @access private
*/
function UpdateCookies($cookies) {
if (sizeof($this->cookies) == 0) {
// no existing cookies: take whatever is new
if (sizeof($cookies) > 0) {
$this->debug('Setting new cookie(s)');
$this->cookies = $cookies;
}
return true;
}
if (sizeof($cookies) == 0) {
// no new cookies: keep what we've got
return true;
}
// merge
foreach ($cookies as $newCookie) {
if (!is_array($newCookie)) {
continue;
}
if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
continue;
}
$newName = $newCookie['name'];
$found = false;
for ($i = 0; $i < count($this->cookies); $i++) {
$cookie = $this->cookies[$i];
if (!is_array($cookie)) {
continue;
}
if (!isset($cookie['name'])) {
continue;
}
if ($newName != $cookie['name']) {
continue;
}
$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
if ($newDomain != $domain) {
continue;
}
$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
if ($newPath != $path) {
continue;
}
$this->cookies[$i] = $newCookie;
$found = true;
$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
break;
}
if (! $found) {
$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
$this->cookies[] = $newCookie;
}
}
return true;
}
}
if (!extension_loaded('soap')) {
/**
* For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
*/
class soapclient extends nusoap_client {
}
}
?>

1938
soap/nusoap/lib/class.wsdl.php Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,209 @@
<?php
/*
The NuSOAP project home is:
http://sourceforge.net/projects/nusoap/
The primary support for NuSOAP is the mailing list:
nusoap-general@lists.sourceforge.net
*/
/**
* caches instances of the wsdl class
*
* @author Scott Nichol <snichol@users.sourceforge.net>
* @author Ingo Fischer <ingo@apollon.de>
* @version $Id: class.wsdlcache.php,v 1.7 2007/04/17 16:34:03 snichol Exp $
* @access public
*/
class nusoap_wsdlcache {
/**
* @var resource
* @access private
*/
var $fplock;
/**
* @var integer
* @access private
*/
var $cache_lifetime;
/**
* @var string
* @access private
*/
var $cache_dir;
/**
* @var string
* @access public
*/
var $debug_str = '';
/**
* constructor
*
* @param string $cache_dir directory for cache-files
* @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited
* @access public
*/
function nusoap_wsdlcache($cache_dir='.', $cache_lifetime=0) {
$this->fplock = array();
$this->cache_dir = $cache_dir != '' ? $cache_dir : '.';
$this->cache_lifetime = $cache_lifetime;
}
/**
* creates the filename used to cache a wsdl instance
*
* @param string $wsdl The URL of the wsdl instance
* @return string The filename used to cache the instance
* @access private
*/
function createFilename($wsdl) {
return $this->cache_dir.'/wsdlcache-' . md5($wsdl);
}
/**
* adds debug data to the class level debug string
*
* @param string $string debug data
* @access private
*/
function debug($string){
$this->debug_str .= get_class($this).": $string\n";
}
/**
* gets a wsdl instance from the cache
*
* @param string $wsdl The URL of the wsdl instance
* @return object wsdl The cached wsdl instance, null if the instance is not in the cache
* @access public
*/
function get($wsdl) {
$filename = $this->createFilename($wsdl);
if ($this->obtainMutex($filename, "r")) {
// check for expired WSDL that must be removed from the cache
if ($this->cache_lifetime > 0) {
if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) {
unlink($filename);
$this->debug("Expired $wsdl ($filename) from cache");
$this->releaseMutex($filename);
return null;
}
}
// see what there is to return
if (!file_exists($filename)) {
$this->debug("$wsdl ($filename) not in cache (1)");
$this->releaseMutex($filename);
return null;
}
$fp = @fopen($filename, "r");
if ($fp) {
$s = implode("", @file($filename));
fclose($fp);
$this->debug("Got $wsdl ($filename) from cache");
} else {
$s = null;
$this->debug("$wsdl ($filename) not in cache (2)");
}
$this->releaseMutex($filename);
return (!is_null($s)) ? unserialize($s) : null;
} else {
$this->debug("Unable to obtain mutex for $filename in get");
}
return null;
}
/**
* obtains the local mutex
*
* @param string $filename The Filename of the Cache to lock
* @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode
* @return boolean Lock successfully obtained ?!
* @access private
*/
function obtainMutex($filename, $mode) {
if (isset($this->fplock[md5($filename)])) {
$this->debug("Lock for $filename already exists");
return false;
}
$this->fplock[md5($filename)] = fopen($filename.".lock", "w");
if ($mode == "r") {
return flock($this->fplock[md5($filename)], LOCK_SH);
} else {
return flock($this->fplock[md5($filename)], LOCK_EX);
}
}
/**
* adds a wsdl instance to the cache
*
* @param object wsdl $wsdl_instance The wsdl instance to add
* @return boolean WSDL successfully cached
* @access public
*/
function put($wsdl_instance) {
$filename = $this->createFilename($wsdl_instance->wsdl);
$s = serialize($wsdl_instance);
if ($this->obtainMutex($filename, "w")) {
$fp = fopen($filename, "w");
if (! $fp) {
$this->debug("Cannot write $wsdl_instance->wsdl ($filename) in cache");
$this->releaseMutex($filename);
return false;
}
fputs($fp, $s);
fclose($fp);
$this->debug("Put $wsdl_instance->wsdl ($filename) in cache");
$this->releaseMutex($filename);
return true;
} else {
$this->debug("Unable to obtain mutex for $filename in put");
}
return false;
}
/**
* releases the local mutex
*
* @param string $filename The Filename of the Cache to lock
* @return boolean Lock successfully released
* @access private
*/
function releaseMutex($filename) {
$ret = flock($this->fplock[md5($filename)], LOCK_UN);
fclose($this->fplock[md5($filename)]);
unset($this->fplock[md5($filename)]);
if (! $ret) {
$this->debug("Not able to release lock for $filename");
}
return $ret;
}
/**
* removes a wsdl instance from the cache
*
* @param string $wsdl The URL of the wsdl instance
* @return boolean Whether there was an instance to remove
* @access public
*/
function remove($wsdl) {
$filename = $this->createFilename($wsdl);
if (!file_exists($filename)) {
$this->debug("$wsdl ($filename) not in cache to be removed");
return false;
}
// ignore errors obtaining mutex
$this->obtainMutex($filename, "w");
$ret = unlink($filename);
$this->debug("Removed ($ret) $wsdl ($filename) from cache");
$this->releaseMutex($filename);
return $ret;
}
}
/**
* For backward compatibility
*/
class wsdlcache extends nusoap_wsdlcache {
}
?>

View File

@@ -0,0 +1,973 @@
<?php
/**
* parses an XML Schema, allows access to it's data, other utility methods.
* imperfect, no validation... yet, but quite functional.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.xmlschema.php,v 1.53 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_xmlschema extends nusoap_base {
// files
var $schema = '';
var $xml = '';
// namespaces
var $enclosingNamespaces;
// schema info
var $schemaInfo = array();
var $schemaTargetNamespace = '';
// types, elements, attributes defined by the schema
var $attributes = array();
var $complexTypes = array();
var $complexTypeStack = array();
var $currentComplexType = null;
var $elements = array();
var $elementStack = array();
var $currentElement = null;
var $simpleTypes = array();
var $simpleTypeStack = array();
var $currentSimpleType = null;
// imports
var $imports = array();
// parser vars
var $parser;
var $position = 0;
var $depth = 0;
var $depth_array = array();
var $message = array();
var $defaultNamespace = array();
/**
* constructor
*
* @param string $schema schema document URI
* @param string $xml xml document URI
* @param string $namespaces namespaces defined in enclosing XML
* @access public
*/
function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
parent::nusoap_base();
$this->debug('nusoap_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()!!');
}
}
/**
* gets a type name for an unnamed type
*
* @param string Element name
* @return string A type name for an unnamed type
* @access private
*/
function CreateTypeName($ename) {
$scope = '';
for ($i = 0; $i < count($this->complexTypeStack); $i++) {
$scope .= $this->complexTypeStack[$i] . '_';
}
return $scope . $ename . '_ContainedType';
}
/**
* 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(preg_match('/^xmlns/',$k)){
//$this->xdebug("$k: $v");
//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
if($ns_prefix = substr(strrchr($k,':'),1)){
//$this->xdebug("Add namespace[$ns_prefix] = $v");
$this->namespaces[$ns_prefix] = $v;
} else {
$this->defaultNamespace[$pos] = $v;
if (! $this->getPrefixFromNamespace($v)) {
$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
}
}
if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
$this->XMLSchemaVersion = $v;
$this->namespaces['xsi'] = $v.'-instance';
}
}
}
foreach($attrs as $k => $v){
// expand each attribute
$k = strpos($k,':') ? $this->expandQname($k) : $k;
$v = strpos($v,':') ? $this->expandQname($v) : $v;
$eAttrs[$k] = $v;
}
$attrs = $eAttrs;
} else {
$attrs = array();
}
// find status, register data
switch($name){
case 'all': // (optional) compositor content for a complexType
case 'choice':
case 'group':
case 'sequence':
//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
//if($name == 'all' || $name == 'sequence'){
// $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
//}
break;
case 'attribute': // complexType attribute
//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
$this->xdebug("parsing attribute:");
$this->appendDebug($this->varDump($attrs));
if (!isset($attrs['form'])) {
// TODO: handle globals
$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
}
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
if (!strpos($v, ':')) {
// no namespace in arrayType attribute value...
if ($this->defaultNamespace[$pos]) {
// ...so use the default
$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
}
}
}
if(isset($attrs['name'])){
$this->attributes[$attrs['name']] = $attrs;
$aname = $attrs['name'];
} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
} else {
$aname = '';
}
} elseif(isset($attrs['ref'])){
$aname = $attrs['ref'];
$this->attributes[$attrs['ref']] = $attrs;
}
if($this->currentComplexType){ // This should *always* be
$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
}
// arrayType attribute
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
$prefix = $this->getPrefix($aname);
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
} else {
$v = '';
}
if(strpos($v,'[,]')){
$this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
}
$v = substr($v,0,strpos($v,'[')); // clip the []
if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
$v = $this->XMLSchemaVersion.':'.$v;
}
$this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
}
break;
case 'complexContent': // (optional) content for a complexType
$this->xdebug("do nothing for element $name");
break;
case 'complexType':
array_push($this->complexTypeStack, $this->currentComplexType);
if(isset($attrs['name'])){
// TODO: what is the scope of named complexTypes that appear
// nested within other c complexTypes?
$this->xdebug('processing named complexType '.$attrs['name']);
//$this->currentElement = false;
$this->currentComplexType = $attrs['name'];
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
// This is for constructs like
// <complexType name="ListOfString" base="soap:Array">
// <sequence>
// <element name="string" type="xsd:string"
// minOccurs="0" maxOccurs="unbounded" />
// </sequence>
// </complexType>
if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
$this->xdebug('complexType is unusual array');
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
} else {
$name = $this->CreateTypeName($this->currentElement);
$this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
$this->currentComplexType = $name;
//$this->currentElement = false;
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
// This is for constructs like
// <complexType name="ListOfString" base="soap:Array">
// <sequence>
// <element name="string" type="xsd:string"
// minOccurs="0" maxOccurs="unbounded" />
// </sequence>
// </complexType>
if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
$this->xdebug('complexType is unusual array');
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
}
$this->complexTypes[$this->currentComplexType]['simpleContent'] = 'false';
break;
case 'element':
array_push($this->elementStack, $this->currentElement);
if (!isset($attrs['form'])) {
if ($this->currentComplexType) {
$attrs['form'] = $this->schemaInfo['elementFormDefault'];
} else {
// global
$attrs['form'] = 'qualified';
}
}
if(isset($attrs['type'])){
$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
if (! $this->getPrefix($attrs['type'])) {
if ($this->defaultNamespace[$pos]) {
$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
$this->xdebug('used default namespace to make type ' . $attrs['type']);
}
}
// This is for constructs like
// <complexType name="ListOfString" base="soap:Array">
// <sequence>
// <element name="string" type="xsd:string"
// minOccurs="0" maxOccurs="unbounded" />
// </sequence>
// </complexType>
if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
}
$this->currentElement = $attrs['name'];
$ename = $attrs['name'];
} elseif(isset($attrs['ref'])){
$this->xdebug("processing element as ref to ".$attrs['ref']);
$this->currentElement = "ref to ".$attrs['ref'];
$ename = $this->getLocalPart($attrs['ref']);
} else {
$type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
$this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
$this->currentElement = $attrs['name'];
$attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
$ename = $attrs['name'];
}
if (isset($ename) && $this->currentComplexType) {
$this->xdebug("add element $ename to complexType $this->currentComplexType");
$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
} elseif (!isset($attrs['ref'])) {
$this->xdebug("add element $ename to elements array");
$this->elements[ $attrs['name'] ] = $attrs;
$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
}
break;
case 'enumeration': // restriction value list member
$this->xdebug('enumeration ' . $attrs['value']);
if ($this->currentSimpleType) {
$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
} elseif ($this->currentComplexType) {
$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
}
break;
case 'extension': // simpleContent or complexContent type extension
$this->xdebug('extension ' . $attrs['base']);
if ($this->currentComplexType) {
$ns = $this->getPrefix($attrs['base']);
if ($ns == '') {
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $this->schemaTargetNamespace . ':' . $attrs['base'];
} else {
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
}
} else {
$this->xdebug('no current complexType to set extensionBase');
}
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 'include':
if (isset($attrs['schemaLocation'])) {
$this->xdebug('include into namespace ' . $this->schemaTargetNamespace . ' from ' . $attrs['schemaLocation']);
$this->imports[$this->schemaTargetNamespace][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
} else {
$this->xdebug('ignoring invalid XML Schema construct: include without schemaLocation attribute');
}
break;
case 'list': // simpleType value list
$this->xdebug("do nothing for element $name");
break;
case 'restriction': // simpleType, simpleContent or complexContent value restriction
$this->xdebug('restriction ' . $attrs['base']);
if($this->currentSimpleType){
$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
} elseif($this->currentComplexType){
$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
if(strstr($attrs['base'],':') == ':Array'){
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
}
}
break;
case 'schema':
$this->schemaInfo = $attrs;
$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
if (isset($attrs['targetNamespace'])) {
$this->schemaTargetNamespace = $attrs['targetNamespace'];
}
if (!isset($attrs['elementFormDefault'])) {
$this->schemaInfo['elementFormDefault'] = 'unqualified';
}
if (!isset($attrs['attributeFormDefault'])) {
$this->schemaInfo['attributeFormDefault'] = 'unqualified';
}
break;
case 'simpleContent': // (optional) content for a complexType
if ($this->currentComplexType) { // This should *always* be
$this->complexTypes[$this->currentComplexType]['simpleContent'] = 'true';
} else {
$this->xdebug("do nothing for element $name because there is no current complexType");
}
break;
case 'simpleType':
array_push($this->simpleTypeStack, $this->currentSimpleType);
if(isset($attrs['name'])){
$this->xdebug("processing simpleType for name " . $attrs['name']);
$this->currentSimpleType = $attrs['name'];
$this->simpleTypes[ $attrs['name'] ] = $attrs;
$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
} else {
$name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
$this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
$this->currentSimpleType = $name;
//$this->currentElement = false;
$this->simpleTypes[$this->currentSimpleType] = $attrs;
$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
}
break;
case 'union': // simpleType type list
$this->xdebug("do nothing for element $name");
break;
default:
$this->xdebug("do not have any logic to process element $name");
}
}
/**
* end-element handler
*
* @param string $parser XML parser object
* @param string $name element name
* @access private
*/
function schemaEndElement($parser, $name) {
// bring depth down a notch
$this->depth--;
// position of current element is equal to the last value left in depth_array for my depth
if(isset($this->depth_array[$this->depth])){
$pos = $this->depth_array[$this->depth];
}
// get element prefix
if ($prefix = $this->getPrefix($name)){
// get unqualified name
$name = $this->getLocalPart($name);
} else {
$prefix = '';
}
// move on...
if($name == 'complexType'){
$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
$this->xdebug($this->varDump($this->complexTypes[$this->currentComplexType]));
$this->currentComplexType = array_pop($this->complexTypeStack);
//$this->currentElement = false;
}
if($name == 'element'){
$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
$this->currentElement = array_pop($this->elementStack);
}
if($name == 'simpleType'){
$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
$this->xdebug($this->varDump($this->simpleTypes[$this->currentSimpleType]));
$this->currentSimpleType = array_pop($this->simpleTypeStack);
}
}
/**
* element content handler
*
* @param string $parser XML parser object
* @param string $data element content
* @access private
*/
function schemaCharacterData($parser, $data){
$pos = $this->depth_array[$this->depth - 1];
$this->message[$pos]['cdata'] .= $data;
}
/**
* serialize the schema
*
* @access public
*/
function serializeSchema(){
$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
$xml = '';
// imports
if (sizeof($this->imports) > 0) {
foreach($this->imports as $ns => $list) {
foreach ($list as $ii) {
if ($ii['location'] != '') {
$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
} else {
$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
}
}
}
}
// complex types
foreach($this->complexTypes as $typeName => $attrs){
$contentStr = '';
// serialize child elements
if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
foreach($attrs['elements'] as $element => $eParts){
if(isset($eParts['ref'])){
$contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
} else {
$contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
foreach ($eParts as $aName => $aValue) {
// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
if ($aName != 'name' && $aName != 'type') {
$contentStr .= " $aName=\"$aValue\"";
}
}
$contentStr .= "/>\n";
}
}
// compositor wraps elements
if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
$contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
}
}
// attributes
if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
foreach($attrs['attrs'] as $attr => $aParts){
$contentStr .= " <$schemaPrefix:attribute";
foreach ($aParts as $a => $v) {
if ($a == 'ref' || $a == 'type') {
$contentStr .= " $a=\"".$this->contractQName($v).'"';
} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
} else {
$contentStr .= " $a=\"$v\"";
}
}
$contentStr .= "/>\n";
}
}
// if restriction
if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
$contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
// complex or simple content
if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
$contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
}
}
// finalize complex type
if($contentStr != ''){
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
} else {
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
}
$xml .= $contentStr;
}
// simple types
if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
foreach($this->simpleTypes as $typeName => $eParts){
$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
if (isset($eParts['enumeration'])) {
foreach ($eParts['enumeration'] as $e) {
$xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
}
}
$xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
}
}
// elements
if(isset($this->elements) && count($this->elements) > 0){
foreach($this->elements as $element => $eParts){
$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
}
}
// attributes
if(isset($this->attributes) && count($this->attributes) > 0){
foreach($this->attributes as $attr => $aParts){
$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
}
}
// finish 'er up
$attr = '';
foreach ($this->schemaInfo as $k => $v) {
if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
$attr .= " $k=\"$v\"";
}
}
$el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
$el .= " xmlns:$nsp=\"$ns\"";
}
$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
return $xml;
}
/**
* adds debug data to the clas level debug string
*
* @param string $string debug data
* @access private
*/
function xdebug($string){
$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
}
/**
* get the PHP type of a user defined type in the schema
* PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
* returns false if no type exists, or not w/ the given namespace
* else returns a string that is either a native php type, or 'struct'
*
* @param string $type name of defined type
* @param string $ns namespace of type
* @return mixed
* @access public
* @deprecated
*/
function getPHPType($type,$ns){
if(isset($this->typemap[$ns][$type])){
//print "found type '$type' and ns $ns in typemap<br>";
return $this->typemap[$ns][$type];
} elseif(isset($this->complexTypes[$type])){
//print "getting type '$type' and ns $ns from complexTypes array<br>";
return $this->complexTypes[$type]['phpType'];
}
return false;
}
/**
* returns an associative array of information about a given type
* returns false if no type exists by the given name
*
* For a complexType typeDef = array(
* 'restrictionBase' => '',
* 'phpType' => '',
* 'compositor' => '(sequence|all)',
* 'elements' => array(), // refs to elements array
* 'attrs' => array() // refs to attributes array
* ... and so on (see addComplexType)
* )
*
* For simpleType or element, the array has different keys.
*
* @param string $type
* @return mixed
* @access public
* @see addComplexType
* @see addSimpleType
* @see addElement
*/
function getTypeDef($type){
//$this->debug("in getTypeDef for type $type");
if (substr($type, -1) == '^') {
$is_element = 1;
$type = substr($type, 0, -1);
} else {
$is_element = 0;
}
if((! $is_element) && isset($this->complexTypes[$type])){
$this->xdebug("in getTypeDef, found complexType $type");
return $this->complexTypes[$type];
} elseif((! $is_element) && isset($this->simpleTypes[$type])){
$this->xdebug("in getTypeDef, found simpleType $type");
if (!isset($this->simpleTypes[$type]['phpType'])) {
// get info for type to tack onto the simple type
// TODO: can this ever really apply (i.e. what is a simpleType really?)
$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
$etype = $this->getTypeDef($uqType);
if ($etype) {
$this->xdebug("in getTypeDef, found type for simpleType $type:");
$this->xdebug($this->varDump($etype));
if (isset($etype['phpType'])) {
$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
}
if (isset($etype['elements'])) {
$this->simpleTypes[$type]['elements'] = $etype['elements'];
}
}
}
return $this->simpleTypes[$type];
} elseif(isset($this->elements[$type])){
$this->xdebug("in getTypeDef, found element $type");
if (!isset($this->elements[$type]['phpType'])) {
// get info for type to tack onto the element
$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
$etype = $this->getTypeDef($uqType);
if ($etype) {
$this->xdebug("in getTypeDef, found type for element $type:");
$this->xdebug($this->varDump($etype));
if (isset($etype['phpType'])) {
$this->elements[$type]['phpType'] = $etype['phpType'];
}
if (isset($etype['elements'])) {
$this->elements[$type]['elements'] = $etype['elements'];
}
if (isset($etype['extensionBase'])) {
$this->elements[$type]['extensionBase'] = $etype['extensionBase'];
}
} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
$this->xdebug("in getTypeDef, element $type is an XSD type");
$this->elements[$type]['phpType'] = 'scalar';
}
}
return $this->elements[$type];
} elseif(isset($this->attributes[$type])){
$this->xdebug("in getTypeDef, found attribute $type");
return $this->attributes[$type];
} elseif (preg_match('/_ContainedType$/', $type)) {
$this->xdebug("in getTypeDef, have an untyped element $type");
$typeDef['typeClass'] = 'simpleType';
$typeDef['phpType'] = 'scalar';
$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
return $typeDef;
}
$this->xdebug("in getTypeDef, did not find $type");
return false;
}
/**
* returns a sample serialization of a given type, or false if no type by the given name
*
* @param string $type name of type
* @return mixed
* @access public
* @deprecated
*/
function serializeTypeDef($type){
//print "in sTD() for type $type<br>";
if($typeDef = $this->getTypeDef($type)){
$str .= '<'.$type;
if(is_array($typeDef['attrs'])){
foreach($typeDef['attrs'] as $attName => $data){
$str .= " $attName=\"{type = ".$data['type']."}\"";
}
}
$str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
if(count($typeDef['elements']) > 0){
$str .= ">";
foreach($typeDef['elements'] as $element => $eData){
$str .= $this->serializeTypeDef($element);
}
$str .= "</$type>";
} elseif($typeDef['typeClass'] == 'element') {
$str .= "></$type>";
} else {
$str .= "/>";
}
return $str;
}
return false;
}
/**
* returns HTML form elements that allow a user
* to enter values for creating an instance of the given type.
*
* @param string $name name for type instance
* @param string $type name of type
* @return string
* @access public
* @deprecated
*/
function typeToForm($name,$type){
// get typedef
if($typeDef = $this->getTypeDef($type)){
// if struct
if($typeDef['phpType'] == 'struct'){
$buffer .= '<table>';
foreach($typeDef['elements'] as $child => $childDef){
$buffer .= "
<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
}
$buffer .= '</table>';
// if array
} elseif($typeDef['phpType'] == 'array'){
$buffer .= '<table>';
for($i=0;$i < 3; $i++){
$buffer .= "
<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
<td><input type='text' name='parameters[".$name."][]'></td></tr>";
}
$buffer .= '</table>';
// if scalar
} else {
$buffer .= "<input type='text' name='parameters[$name]'>";
}
} else {
$buffer .= "<input type='text' name='parameters[$name]'>";
}
return $buffer;
}
/**
* adds a complex type to the schema
*
* example: array
*
* addType(
* 'ArrayOfstring',
* 'complexType',
* 'array',
* '',
* 'SOAP-ENC:Array',
* array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
* 'xsd:string'
* );
*
* example: PHP associative array ( SOAP Struct )
*
* addType(
* 'SOAPStruct',
* 'complexType',
* 'struct',
* 'all',
* array('myVar'=> array('name'=>'myVar','type'=>'string')
* );
*
* @param name
* @param typeClass (complexType|simpleType|attribute)
* @param phpType: currently supported are array and struct (php assoc array)
* @param compositor (all|sequence|choice)
* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
* @param elements = array ( name = array(name=>'',type=>'') )
* @param attrs = array(
* array(
* 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
* "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
* )
* )
* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
* @access public
* @see getTypeDef
*/
function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
$this->complexTypes[$name] = array(
'name' => $name,
'typeClass' => $typeClass,
'phpType' => $phpType,
'compositor'=> $compositor,
'restrictionBase' => $restrictionBase,
'elements' => $elements,
'attrs' => $attrs,
'arrayType' => $arrayType
);
$this->xdebug("addComplexType $name:");
$this->appendDebug($this->varDump($this->complexTypes[$name]));
}
/**
* adds a simple type to the schema
*
* @param string $name
* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
* @param string $typeClass (should always be simpleType)
* @param string $phpType (should always be scalar)
* @param array $enumeration array of values
* @access public
* @see nusoap_xmlschema
* @see getTypeDef
*/
function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
$this->simpleTypes[$name] = array(
'name' => $name,
'typeClass' => $typeClass,
'phpType' => $phpType,
'type' => $restrictionBase,
'enumeration' => $enumeration
);
$this->xdebug("addSimpleType $name:");
$this->appendDebug($this->varDump($this->simpleTypes[$name]));
}
/**
* adds an element to the schema
*
* @param array $attrs attributes that must include name and type
* @see nusoap_xmlschema
* @access public
*/
function addElement($attrs) {
if (! $this->getPrefix($attrs['type'])) {
$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
}
$this->elements[ $attrs['name'] ] = $attrs;
$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
$this->xdebug("addElement " . $attrs['name']);
$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
}
}
/**
* Backward compatibility
*/
class XMLSchema extends nusoap_xmlschema {
}
?>

8148
soap/nusoap/lib/nusoap.php Executable file

File diff suppressed because it is too large Load Diff

501
soap/nusoap/lib/nusoapmime.php Executable file
View File

@@ -0,0 +1,501 @@
<?php
/*
$Id: nusoapmime.php,v 1.13 2010/04/26 20:15:08 snichol Exp $
NuSOAP - Web Services Toolkit for PHP
Copyright (c) 2002 NuSphere Corporation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The NuSOAP project home is:
http://sourceforge.net/projects/nusoap/
The primary support for NuSOAP is the mailing list:
nusoap-general@lists.sourceforge.net
If you have any questions or comments, please email:
Dietrich Ayala
dietrich@ganx4.com
http://dietrich.ganx4.com/nusoap
NuSphere Corporation
http://www.nusphere.com
*/
/*require_once('nusoap.php');*/
/* PEAR Mail_MIME library */
require_once('Mail/mimeDecode.php');
require_once('Mail/mimePart.php');
/**
* nusoap_client_mime client supporting MIME attachments defined at
* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
*
* @author Scott Nichol <snichol@users.sourceforge.net>
* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
* @version $Id: nusoapmime.php,v 1.13 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_client_mime extends nusoap_client {
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $requestAttachments = array();
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $responseAttachments;
/**
* @var string
* @access private
*/
var $mimeContentType;
/**
* adds a MIME attachment to the current request.
*
* If the $data parameter contains an empty string, this method will read
* the contents of the file named by the $filename parameter.
*
* If the $cid parameter is false, this method will generate the cid.
*
* @param string $data The data of the attachment
* @param string $filename The filename of the attachment (default is empty string)
* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
* @param string $cid The content-id (cid) of the attachment (default is false)
* @return string The content-id (cid) of the attachment
* @access public
*/
function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
if (! $cid) {
$cid = md5(uniqid(time()));
}
$info['data'] = $data;
$info['filename'] = $filename;
$info['contenttype'] = $contenttype;
$info['cid'] = $cid;
$this->requestAttachments[] = $info;
return $cid;
}
/**
* clears the MIME attachments for the current request.
*
* @access public
*/
function clearAttachments() {
$this->requestAttachments = array();
}
/**
* gets the MIME attachments from the current response.
*
* Each array element in the return is an associative array with keys
* data, filename, contenttype, cid. These keys correspond to the parameters
* for addAttachment.
*
* @return array The attachments.
* @access public
*/
function getAttachments() {
return $this->responseAttachments;
}
/**
* gets the HTTP body for the current request.
*
* @param string $soapmsg The SOAP payload
* @return string The HTTP body, which includes the SOAP payload
* @access private
*/
function getHTTPBody($soapmsg) {
if (count($this->requestAttachments) > 0) {
$params['content_type'] = 'multipart/related; type="text/xml"';
$mimeMessage = new Mail_mimePart('', $params);
unset($params);
$params['content_type'] = 'text/xml';
$params['encoding'] = '8bit';
$params['charset'] = $this->soap_defencoding;
$mimeMessage->addSubpart($soapmsg, $params);
foreach ($this->requestAttachments as $att) {
unset($params);
$params['content_type'] = $att['contenttype'];
$params['encoding'] = 'base64';
$params['disposition'] = 'attachment';
$params['dfilename'] = $att['filename'];
$params['cid'] = $att['cid'];
if ($att['data'] == '' && $att['filename'] <> '') {
if ($fd = fopen($att['filename'], 'rb')) {
$data = fread($fd, filesize($att['filename']));
fclose($fd);
} else {
$data = '';
}
$mimeMessage->addSubpart($data, $params);
} else {
$mimeMessage->addSubpart($att['data'], $params);
}
}
$output = $mimeMessage->encode();
$mimeHeaders = $output['headers'];
foreach ($mimeHeaders as $k => $v) {
$this->debug("MIME header $k: $v");
if (strtolower($k) == 'content-type') {
// PHP header() seems to strip leading whitespace starting
// the second line, so force everything to one line
$this->mimeContentType = str_replace("\r\n", " ", $v);
}
}
return $output['body'];
}
return parent::getHTTPBody($soapmsg);
}
/**
* gets the HTTP content type for the current request.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type for the current request.
* @access private
*/
function getHTTPContentType() {
if (count($this->requestAttachments) > 0) {
return $this->mimeContentType;
}
return parent::getHTTPContentType();
}
/**
* gets the HTTP content type charset for the current request.
* returns false for non-text content types.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type charset for the current request.
* @access private
*/
function getHTTPContentTypeCharset() {
if (count($this->requestAttachments) > 0) {
return false;
}
return parent::getHTTPContentTypeCharset();
}
/**
* processes SOAP message returned from server
*
* @param array $headers The HTTP headers
* @param string $data unprocessed response data from server
* @return mixed value of the message, decoded into a PHP type
* @access private
*/
function parseResponse($headers, $data) {
$this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
$this->responseAttachments = array();
if (strstr($headers['content-type'], 'multipart/related')) {
$this->debug('Decode multipart/related');
$input = '';
foreach ($headers as $k => $v) {
$input .= "$k: $v\r\n";
}
$params['input'] = $input . "\r\n" . $data;
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$structure = Mail_mimeDecode::decode($params);
foreach ($structure->parts as $part) {
if (!isset($part->disposition) && (strstr($part->headers['content-type'], 'text/xml'))) {
$this->debug('Have root part of type ' . $part->headers['content-type']);
$root = $part->body;
$return = parent::parseResponse($part->headers, $part->body);
} else {
$this->debug('Have an attachment of type ' . $part->headers['content-type']);
$info['data'] = $part->body;
$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
$info['contenttype'] = $part->headers['content-type'];
$info['cid'] = $part->headers['content-id'];
$this->responseAttachments[] = $info;
}
}
if (isset($return)) {
$this->responseData = $root;
return $return;
}
$this->setError('No root part found in multipart/related content');
return '';
}
$this->debug('Not multipart/related');
return parent::parseResponse($headers, $data);
}
}
/*
* For backwards compatiblity, define soapclientmime unless the PHP SOAP extension is loaded.
*/
if (!extension_loaded('soap')) {
class soapclientmime extends nusoap_client_mime {
}
}
/**
* nusoap_server_mime server supporting MIME attachments defined at
* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
*
* @author Scott Nichol <snichol@users.sourceforge.net>
* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
* @version $Id: nusoapmime.php,v 1.13 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_server_mime extends nusoap_server {
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $requestAttachments = array();
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $responseAttachments;
/**
* @var string
* @access private
*/
var $mimeContentType;
/**
* adds a MIME attachment to the current response.
*
* If the $data parameter contains an empty string, this method will read
* the contents of the file named by the $filename parameter.
*
* If the $cid parameter is false, this method will generate the cid.
*
* @param string $data The data of the attachment
* @param string $filename The filename of the attachment (default is empty string)
* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
* @param string $cid The content-id (cid) of the attachment (default is false)
* @return string The content-id (cid) of the attachment
* @access public
*/
function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
if (! $cid) {
$cid = md5(uniqid(time()));
}
$info['data'] = $data;
$info['filename'] = $filename;
$info['contenttype'] = $contenttype;
$info['cid'] = $cid;
$this->responseAttachments[] = $info;
return $cid;
}
/**
* clears the MIME attachments for the current response.
*
* @access public
*/
function clearAttachments() {
$this->responseAttachments = array();
}
/**
* gets the MIME attachments from the current request.
*
* Each array element in the return is an associative array with keys
* data, filename, contenttype, cid. These keys correspond to the parameters
* for addAttachment.
*
* @return array The attachments.
* @access public
*/
function getAttachments() {
return $this->requestAttachments;
}
/**
* gets the HTTP body for the current response.
*
* @param string $soapmsg The SOAP payload
* @return string The HTTP body, which includes the SOAP payload
* @access private
*/
function getHTTPBody($soapmsg) {
if (count($this->responseAttachments) > 0) {
$params['content_type'] = 'multipart/related; type="text/xml"';
$mimeMessage = new Mail_mimePart('', $params);
unset($params);
$params['content_type'] = 'text/xml';
$params['encoding'] = '8bit';
$params['charset'] = $this->soap_defencoding;
$mimeMessage->addSubpart($soapmsg, $params);
foreach ($this->responseAttachments as $att) {
unset($params);
$params['content_type'] = $att['contenttype'];
$params['encoding'] = 'base64';
$params['disposition'] = 'attachment';
$params['dfilename'] = $att['filename'];
$params['cid'] = $att['cid'];
if ($att['data'] == '' && $att['filename'] <> '') {
if ($fd = fopen($att['filename'], 'rb')) {
$data = fread($fd, filesize($att['filename']));
fclose($fd);
} else {
$data = '';
}
$mimeMessage->addSubpart($data, $params);
} else {
$mimeMessage->addSubpart($att['data'], $params);
}
}
$output = $mimeMessage->encode();
$mimeHeaders = $output['headers'];
foreach ($mimeHeaders as $k => $v) {
$this->debug("MIME header $k: $v");
if (strtolower($k) == 'content-type') {
// PHP header() seems to strip leading whitespace starting
// the second line, so force everything to one line
$this->mimeContentType = str_replace("\r\n", " ", $v);
}
}
return $output['body'];
}
return parent::getHTTPBody($soapmsg);
}
/**
* gets the HTTP content type for the current response.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type for the current response.
* @access private
*/
function getHTTPContentType() {
if (count($this->responseAttachments) > 0) {
return $this->mimeContentType;
}
return parent::getHTTPContentType();
}
/**
* gets the HTTP content type charset for the current response.
* returns false for non-text content types.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type charset for the current response.
* @access private
*/
function getHTTPContentTypeCharset() {
if (count($this->responseAttachments) > 0) {
return false;
}
return parent::getHTTPContentTypeCharset();
}
/**
* processes SOAP message received from client
*
* @param array $headers The HTTP headers
* @param string $data unprocessed request data from client
* @return mixed value of the message, decoded into a PHP type
* @access private
*/
function parseRequest($headers, $data) {
$this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
$this->requestAttachments = array();
if (strstr($headers['content-type'], 'multipart/related')) {
$this->debug('Decode multipart/related');
$input = '';
foreach ($headers as $k => $v) {
$input .= "$k: $v\r\n";
}
$params['input'] = $input . "\r\n" . $data;
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$structure = Mail_mimeDecode::decode($params);
foreach ($structure->parts as $part) {
if (!isset($part->disposition) && (strstr($part->headers['content-type'], 'text/xml'))) {
$this->debug('Have root part of type ' . $part->headers['content-type']);
$return = parent::parseRequest($part->headers, $part->body);
} else {
$this->debug('Have an attachment of type ' . $part->headers['content-type']);
$info['data'] = $part->body;
$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
$info['contenttype'] = $part->headers['content-type'];
$info['cid'] = $part->headers['content-id'];
$this->requestAttachments[] = $info;
}
}
if (isset($return)) {
return $return;
}
$this->setError('No root part found in multipart/related content');
return;
}
$this->debug('Not multipart/related');
return parent::parseRequest($headers, $data);
}
}
/*
* For backwards compatiblity
*/
class nusoapservermime extends nusoap_server_mime {
}
?>

24
soap/test.php Executable file
View File

@@ -0,0 +1,24 @@
<?php
ini_set('display_errors',1);
ini_set("soap.wsdl_cache_enabled", "0");
//header('Content-Type: text/html; charset=utf-8');
require_once('nusoap/lib/nusoap.php');
//Db::getInstance()->execute("UPDATE `e5_pl`.`ps_orders` SET `current_state`='10' WHERE `reference`='NTXEZDQSJ'");
// pobieranie kategorii z E5CRM i aktualizowanie ich w sklepie Presta Shop
$soap = new SoapClient("https://95.50.148.50/e5new/soap.php?wsdllllllll", array('login' => "ll", 'password' => "test5555", 'version' => 1));
$result = $soap->ecm_get_categories("ll", "test5555", "5a7c1379-a50b-3ce6-f96b-4ce4e7a9496a");
foreach ($result as $data) {
//echo str_replace("<22>", "", convertToCoding($data->name, "utf-8"))." (".mb_detect_encoding($data->name, 'UTF-8, ISO-8859-1').")<BR>";
echo $data->name."<BR>";
}
?>

10
soap/wsdl_test.php Executable file
View File

@@ -0,0 +1,10 @@
<?php
include('nusoap/lib/nusoap.php');
$client = new soapclient('http://e5.pl/new/WSDL/WSDL.php?wsdl',array('encoding' => 'UTF-8'));
//ini_set("soap.wsdl_cache_enabled", "0");
$result = $client->UpdateOrder('YNNQMSVEW', 2);
?>