Login   Register  
PHP Classes
elePHPant
Icontem

return Array of Objects

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us

      PHP WSDL Generator  >  All threads  >  return Array of Objects  >  (Un) Subscribe thread alerts  
Subject:return Array of Objects
Summary:Object type definition not included in WSDL when returned in arr
Messages:4
Author:Klaus Schmid
Date:2010-03-18 10:26:02
Update:2010-03-18 15:07:51
 

  1. return Array of Objects   Reply  
Picture of Klaus Schmid
Klaus Schmid
2010-03-18 10:26:02
Hello,

first of all great work you did there with the WSDL generator. It's easy to use and saves a lot of time.

I'm having a problem though when I return arrays of objects.

Example: method comment (like in example_class2)
/**
* some doc comment
* @param string $someParam
* @return MyValueObject[]
*/

The WSDL specifies it to be a type="urn:ArrayOfMyValueObject" which is correct, but this type is never explained in the WSDL which leads to Axis breaking down when I try to create the stubs.

I have tried the following:
- manually adding the class definition files to the WSDLCreator
- setting an URL to all Classes using setClassesGeneralURL
- setting a specific URL to the type using addURLToTypens

When I specify the returnvalue as @return MyValueObject, it gets parsed but an error is raised since it is just a value object without any methods.

Did I forget some important part to make it work / did I read the docs not careful enough? If so, please feel free to slap my face :-)
No but seriously, what do I need to do to make this work?

Thanks in advance.

  2. Re: return Array of Objects   Reply  
Picture of Klaus Schmid
Klaus Schmid
2010-03-18 12:15:57 - In reply to message 1 from Klaus Schmid
Ok I have found that it immediately works if I add a dummy method to the class that sits in the array. This is a workaround I can live with at first.

But the next problem is that @var declarations of complex types seem to get ignored even if the corresponding type contains methods. Example:

/**
* @var MySecondValueObject[]
*/
public $variable = array();

in the WSDL, I keep on getting:
<xsd:element name="variable" type="anyType"/>


How can I trick the generator into something like this?
<xsd:element name="variable" type="urn:ArrayOfMySecondValueObject"/>

Thank you.

  3. Re: return Array of Objects   Reply  
Picture of Klaus Schmid
Klaus Schmid
2010-03-18 13:15:36 - In reply to message 2 from Klaus Schmid
I took the freedom of modifying the WSDLCreator a little so that Object Arrays will get printed when they are in a class variable.

(1) in createWSDL(), section // add types, I replaced the line
$varType = isset($this->xsd[$varType]) ? "xsd:".$this->xsd[strtolower($varType)] : "anyType";

with
if (substr($varType, -2) == "[]" || substr($varType, -3) == "[];") {
$this->addComplexTypes($varType);
$varType = "urn:ArrayOf".trim(substr($varType,0,-2));
} else if (isset($this->xsd[$varType])) {
$varType = "xsd:".$this->xsd[strtolower($varType)];
} else {
$varType = "anyType";
}

(2) in addComplexTypes($type), I added a
$this->addTypens($complexType);

right behind
$this->complexTypens[$type] = $xsdComplexType;

(3) (this I added to get the complex types at all)
in createMessage ($name, $returnType = false, $params = array())
I added
$this->addComplexTypes($type);

right between
} elseif (substr($type, -2) == "[]" || substr($type, -3) == "[];") {
$type = "urn:ArrayOf".trim(substr($type,0,-2));


-> hope this is understandable. I know that's not really clean code, but so far it does what it should. Feel free to comment.

  4. Re: return Array of Objects   Reply  
Picture of Klaus Schmid
Klaus Schmid
2010-03-18 15:07:51 - In reply to message 3 from Klaus Schmid
Sorry to bother you again - but for the sake of completeness I want to add this here: my last edit was incomplete, the actual complexType definition was not written out when it was specified as a @var. So I made a little change to the add types section in createWSDL():


// add types
if (is_array($this->typensDefined) && count($this->typensDefined) > 0) {
$types = new XMLCreator("types");
$xsdSchema = new XMLCreator("xsd:schema");
$xsdSchema->setAttribute("xmlns", "http://www.w3.org/2001/XMLSchema");
$xsdSchema->setAttribute("targetNamespace", "urn:".$this->name);
$vars = $this->PHPParser->getClassesVars();
// this was the original loop. it's now replaced by a foreach inside a while
// don't worry, no type will be iterated twice.
// the while is only there to also handle types that have been added while inside the loop
//foreach ($this->typensDefined as $typensDefined) {
while (count($this->typensDefined) > 0) {
foreach ($this->typensDefined as $typensKey=>$typensDefined) {
$complexType = new XMLCreator("xsd:complexType");
$complexType->setAttribute("name", $typensDefined);
$all = new XMLCreator("xsd:all");
if (isset($vars[$typensDefined]) && is_array($vars[$typensDefined])) {
ksort($vars[$typensDefined]);
foreach ($vars[$typensDefined] as $varName=>$varType) {
$element = new XMLCreator("xsd:element");
$element->setAttribute("name", $varName);
// this was the original line.
//$varType = isset($this->xsd[$varType]) ? "xsd:".$this->xsd[strtolower($varType)] : "anyType";

if (substr($varType, -2) == "[]" || substr($varType, -3) == "[];") {
$this->addComplexTypes($varType);
$varType = "urn:ArrayOf".trim(substr($varType,0,-2));
} else if (isset($this->xsd[$varType])) {
$varType = "xsd:".$this->xsd[strtolower($varType)];
} else {
$varType = "anyType";
}

$element->setAttribute("type", $varType);
$all->addChild($element);
}
}
$complexType->addChild($all);
$xsdSchema->addChild($complexType);
foreach ($this->complexTypens as $ct) {
$xsdSchema->addChild($ct);
}
unset($this->typensDefined[$typensKey]);
}
}
$types->addChild($xsdSchema);
$this->WSDLXML->addChild($types);
}