function addSchemaFromMap(&$map) { if (!$map) { return; } foreach ($map as $_type_name => $_type_def) { list($typens, $type) = $this->_getTypeNs($_type_name); if ($typens == 'xsd') { // cannot add to xsd, lets use method_namespace $typens = 'tns'; } $schema =& $this->_getSchema(array_search($typens, $this->namespaces)); if (!$this->_ifComplexTypeExists($schema['complexType'], $type)) { $ctype =& $schema['complexType'][]; $ctype['attr']['name'] = $type; foreach ($_type_def as $_varname => $_vartype) { if (!is_int($_varname)) { list($_vartypens, $_vartype) = $this->_getTypeNs($_vartype); $ctype['all']['attr'] = ''; $el =& $ctype['all']['element'][]; $el['attr']['name'] = $_varname; $el['attr']['type'] = $_vartypens . ':' . $_vartype; } else { $ctype['complexContent']['attr'] = ''; $ctype['complexContent']['restriction']['attr']['base'] = SOAP_BASE::SOAPENCPrefix() . ':Array'; foreach ($_vartype as $array_type) { list($_vartypens, $_vartype) = $this->_getTypeNs($array_type); $ctype['complexContent']['restriction']['attribute']['attr']['ref'] = SOAP_BASE::SOAPENCPrefix() . ':arrayType'; $ctype['complexContent']['restriction']['attribute']['attr']['wsdl:arrayType'] = $_vartypens . ':' . $_vartype . '[]'; } } } } } }
/** * Serializes a value, array or object according to the rules set by this * object. * * @see SOAP_Value * * @param mixed $value The actual value. * @param QName $name The value name. * @param QName $type The value type. * @param array $options A list of encoding and serialization options. * @param array $attributes A hash of additional attributes. * @param string $artype The type of any array elements. */ function _serializeValue($value, $name = null, $type = null, $options = array(), $attributes = array(), $artype = '') { $namespaces = array(); $arrayType = $array_depth = $xmlout_value = null; $typePrefix = $elPrefix = $xmlout_arrayType = ''; $xmlout_type = $xmlns = $ptype = $array_type_ns = ''; if (!$name->name || is_numeric($name->name)) { $name->name = 'item'; } if ($this->_wsdl) { list($ptype, $arrayType, $array_type_ns, $array_depth) = $this->_wsdl->getSchemaType($type, $name); } if (!$arrayType) { $arrayType = $artype; } if (!$ptype) { $ptype = $this->_getType($value); } if (!$type) { $type = new QName($ptype); } if (strcasecmp($ptype, 'Struct') == 0 || strcasecmp($type->name, 'Struct') == 0) { // Struct $vars = is_object($value) ? get_object_vars($value) : $value; if (is_array($vars)) { foreach (array_keys($vars) as $k) { // Hide private vars. if ($k[0] == '_') { continue; } if (is_object($vars[$k])) { if (is_a($vars[$k], 'SOAP_Value')) { $xmlout_value .= $vars[$k]->serialize($this); } else { // XXX get the members and serialize them instead // converting to an array is more overhead than we // should really do. $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), new QName($k, $this->_section5 ? null : $name->namepace), null, $options); } } else { $xmlout_value .= $this->_serializeValue($vars[$k], new QName($k, $this->_section5 ? null : $name->namespace), false, $options); } } } } elseif (strcasecmp($ptype, 'Array') == 0 || strcasecmp($type->name, 'Array') == 0) { // Array. $type = new QName('Array', SOAP_SCHEMA_ENCODING); $numtypes = 0; $value = (array) $value; // XXX this will be slow on larger arrays. Basically, it flattens // arrays to allow us to serialize multi-dimensional arrays. We // only do this if arrayType is set, which will typically only // happen if we are using WSDL if (isset($options['flatten']) || $arrayType && (strchr($arrayType, ',') || strstr($arrayType, ']['))) { $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value); } $array_type = $array_type_prefix = ''; if ($numtypes != 1) { $arrayTypeQName = new QName($arrayType); $arrayType = $arrayTypeQName->name; $array_types = array(); $array_val = null; // Serialize each array element. $ar_size = count($value); foreach ($value as $array_val) { if (is_a($array_val, 'SOAP_Value')) { $array_type = $array_val->type; $array_types[$array_type] = 1; $array_type_ns = $array_val->type_namespace; $xmlout_value .= $array_val->serialize($this); } else { $array_type = $this->_getType($array_val); $array_types[$array_type] = 1; if (empty($options['keep_arrays_flat'])) { $xmlout_value .= $this->_serializeValue($array_val, new QName('item', $this->_section5 ? null : $name->namespace), new QName($array_type), $options); } else { $xmlout_value .= $this->_serializeValue($array_val, $name, new QName($array_type), $options, $attributes); } } } if (!$arrayType) { $numtypes = count($array_types); if ($numtypes == 1) { $arrayType = $array_type; } // Using anyType is more interoperable. if ($array_type == 'Struct') { $array_type = ''; } elseif ($array_type == 'Array') { $arrayType = 'anyType'; $array_type_prefix = 'xsd'; } else { if (!$arrayType) { $arrayType = $array_type; } } } } if (!$arrayType || $numtypes > 1) { // Should reference what schema we're using. $arrayType = 'xsd:anyType'; } else { if ($array_type_ns) { $array_type_prefix = $this->_getNamespacePrefix($array_type_ns); } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) { $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; } elseif (isset($this->_typemap[SOAP_SCHEMA_ENCODING][$arrayType])) { $array_type_prefix = SOAP_BASE::SOAPENCPrefix(); } if ($array_type_prefix) { $arrayType = $array_type_prefix . ':' . $arrayType; } } $xmlout_arrayType = ' ' . SOAP_BASE::SOAPENCPrefix() . ':arrayType="' . $arrayType; if ($array_depth != null) { for ($i = 0; $i < $array_depth; $i++) { $xmlout_arrayType .= '[]'; } } $xmlout_arrayType .= "[{$ar_size}]\""; } elseif ($value instanceof SOAP_Value) { $xmlout_value = $value->serialize($this); } elseif ($type->name == 'string') { $xmlout_value = htmlspecialchars($value); } elseif ($type->name == 'rawstring') { $xmlout_value = $value; } elseif ($type->name == 'boolean') { $xmlout_value = $value ? 'true' : 'false'; } else { $xmlout_value = $value; } // Add namespaces. if ($name->namespace) { $elPrefix = $this->_getNamespacePrefix($name->namespace); if ($elPrefix) { $xmlout_name = $elPrefix . ':' . $name->name; } else { $xmlout_name = $name->name; } } else { $xmlout_name = $name->name; } if ($type->namespace) { $typePrefix = false; if (empty($options['no_type_prefix'])) { $typePrefix = $this->_getNamespacePrefix($type->namespace); } if ($typePrefix) { $xmlout_type = $typePrefix . ':' . $type->name; } else { $xmlout_type = $type->name; } } elseif ($type->name && isset($this->_typemap[$this->_XMLSchemaVersion][$type->name])) { $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion]; if ($typePrefix) { $xmlout_type = $typePrefix . ':' . $type->name; } else { $xmlout_type = $type->name; } } // Handle additional attributes. $xml_attr = ''; if (count($attributes)) { foreach ($attributes as $k => $v) { $kqn = new QName($k); $vqn = new QName($v); $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"'; } } // Store the attachment for mime encoding. if (isset($options['attachment']) && !PEAR::isError($options['attachment'])) { $this->_attachments[] = $options['attachment']; } if ($this->_section5) { if ($xmlout_type) { $xmlout_type = " xsi:type=\"{$xmlout_type}\""; } if (is_null($xmlout_value)) { $xml = "\r\n<{$xmlout_name}{$xmlout_type}{$xmlns}{$xmlout_arrayType}" . "{$xml_attr} xsi:nil=\"true\"/>"; } else { $xml = "\r\n<{$xmlout_name}{$xmlout_type}{$xmlns}{$xmlout_arrayType}" . "{$xml_attr}>{$xmlout_value}</{$xmlout_name}>"; } } elseif ($type->name == 'Array' && !empty($options['keep_arrays_flat'])) { $xml = $xmlout_value; } else { if (is_null($xmlout_value)) { $xml = "\r\n<{$xmlout_name}{$xmlns}{$xml_attr}/>"; } else { $xml = "\r\n<{$xmlout_name}{$xmlns}{$xml_attr}>" . $xmlout_value . "</{$xmlout_name}>"; } } return $xml; }
/** * Initialise the SOAP_WSDL tree (destructive). * * If the object has already been initialised, the only effect * will be to change the tns namespace to the new service name. * * @param $service_name Name of the WSDL <service> * @access private */ function _initialise($service_name) { // Set up the basic namespaces that all WSDL definitions use. $this->wsdl->namespaces['wsdl'] = SCHEMA_WSDL; // WSDL language $this->wsdl->namespaces['soap'] = SCHEMA_SOAP; // WSDL SOAP bindings $this->wsdl->namespaces[$this->tnsPrefix] = 'urn:' . $service_name; // Target namespace $this->wsdl->namespaces['xsd'] = array_search('xsd', $this->_namespaces); // XML Schema $this->wsdl->namespaces[SOAP_BASE::SOAPENCPrefix()] = array_search(SOAP_BASE::SOAPENCPrefix(), $this->_namespaces); // SOAP types // XXX Refactor $namespace/$ns for Shane :-) unset($this->wsdl->ns['urn:' . $service_name]); $this->wsdl->ns += array_flip($this->wsdl->namespaces); // Imports are not implemented in WSDL generation from classes. // *** <wsdl:import> *** }