Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Associative arrays #29

Open
dan-klasson opened this issue Jan 17, 2012 · 12 comments
Open

Associative arrays #29

dan-klasson opened this issue Jan 17, 2012 · 12 comments
Labels

Comments

@dan-klasson
Copy link

In order to pass or return associative arrays, do I need to use "ComplexType"? It would be great with an example of that too. Thanks.

@christiankerl
Copy link

yes, you have to create a custom complex type, it might look like this:

<?php

use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap;

/**
 * Implement more interfaces like Countable and IteratorAggregate
 */
class Map : ArrayAccess
{
    /**
     * @Soap\ComplexType("MapEntry[]")
     */
    private $entries = array();

    public function offsetExists($key)
    {
        return isset($this->entries[$key]);
    }

    public function offsetGet($key)
    {
        return isset($this->entries[$key]) ? $this->entries[$key]->value : null;
    }

    public function offsetSet($key, $value)
    {
        $this->entries[$key] = new MapEntry($key, $value);
    }

    public function offsetUnset($key)
    {
        unset($this->entries[$key]);
    }
}

class MapEntry
{
    /**
     * @Soap\ComplexType("string")
     */
    public $key;

    /**
     * change string to another type, if your values aren't strings
     * @Soap\ComplexType("string")
     */
    public $value;

    public function __construct($key, $value)
    {
        $this->key = $key;
        $this->value = $value;
    }
}

you can then specify Map as a return type of one of your controller methods.

hope this helps you!

@francisbesset we can use this as a starting point for an example at the official website

@gquemener
Copy link

Hello,

I'm having some trouble while using a complexType as a Parameter of one of my method.
Here's the code:

The Controller
    /**
     * @Soap\Method("declareSale")
     * @Soap\Param("saleHours", phpType = "SaleHours")
     * @Soap\Result(phpType = "DeclareSaleReturn")
     */
    public function declareSaleAction($saleHours)
    {
        var_dump($saleHours);die;
    }
class SaleHours implements \ArrayAccess
{
    /**
     * @Soap\ComplexType("SaleHour[]")
     */
    public $saleHours = array();

    public function __construct($saleHours) {
        $this->saleHours = $saleHours;
    }

    public function offsetExists($key)
    {
        return isset($this->saleHours[$key]);
    }

    public function offsetGet($key)
    {
        return isset($this->saleHours[$key]) ? $this->saleHours[$key]->value : null;
    }

    public function offsetSet($key, $value)
    {
        $this->saleHours[$key] = new MapEntry($key, $value);
    }

    public function offsetUnset($key)
    {
        unset($this->saleHours[$key]);
    }
}
class SaleHour
{
    /**
     * @Soap\ComplexType("string")
     */
    public $hourStartTime;

    /**
     * @Soap\ComplexType("string")
     */
    public $hourTitle;

    public function __construct($hourStartTime, $hourTitle) {
        $this->hourStartTime = $hourStartTime;
        $this->hourTitle = $hourTitle;
    }
}

and the request:

        <?xml version="1.0"?>
        <soapenv:Envelope
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:ns="/api/1.0/">
            <soapenv:Header/>
            <soapenv:Body>
                <ns:declareSale>
                    <saleHours>
                        <saleHour>
                            <hourStartTime>10:00</hourStartTime>
                            <hourTitle>Camion</hourTitle>
                        </saleHour>
                        <saleHour>
                            <hourStartTime>12:00</hourStartTime>
                            <hourTitle>Voiture</hourTitle>
                        </saleHour>
                    </saleHours>
                </ns:declareSale>
            </soapenv:Body>
        </soapenv:Envelope>

And the controller action always output

class SaleHours#309 (1) {
  public $saleHours =>
  array(0) {
  }
}

So i've tried the following controller action modification:

The Controller
    /**
     * @Soap\Method("declareSale")
     * @Soap\Param("saleHours", phpType = "SaleHour[]")
     * @Soap\Result(phpType = "DeclareSaleReturn")
     */
    public function declareSaleAction($saleHours)
    {
        var_dump($saleHours);die;
    }

and the controller action just output

array(0) {
}

Can you please give me a hint on what I'm doing wrong, please?
Many thanks in advance!

@gquemener
Copy link

I've finally found a solution on my problem.

Soap array type involves that you embed <item> inside your array parameter. Otherwise, It will just not understant and provide no element (he could have said, hey guy I see some stuff in your array but I can't understand it)...

As I'm a nice guy, here's a sample request to send an array as a parameter:

        <?xml version="1.0"?>
        <SOAP-ENV:Envelope
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <SOAP-ENV:Header/>
            <SOAP-ENV:Body>
                <vp:declareSale xmlns:vp="/api/1.0/">
                    <saleHours SOAP-ENC:arrayType="vp:SaleHour[2]" xsi:type="SOAP-ENC:Array">
                        <item>
                            <hourStartTime>10:00</hourStartTime>
                            <hourTitle>Camion</hourTitle>
                        </item>
                        <item>
                            <hourStartTime>12:00</hourStartTime>
                            <hourTitle>Voiture</hourTitle>
                        </item>
                    </saleHours>
                </vp:declareSale>
            </SOAP-ENV:Body>
        </SOAP-ENV:Envelope>

@saidmoya12
Copy link

How to remove <item></item> tags?

@gquemener
Copy link

Personaly, I haven't succeed in removing them, but SOAP Spec tells us that it might be possible.

Check the 5.4.2 Chapter on Arrays here: http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383522

@francisbesset
Copy link
Member

The problem still exists?

@gquemener
Copy link

AFAIK, there is no problem except soap...

francisbesset added a commit that referenced this issue Feb 27, 2013
@francisbesset
Copy link
Member

I committed a solution. Maybe not the better but it works.
You can see: ea4d031, BeSimple/BeSimpleSoapCommon@db885b2 and http://besim.pl/SoapBundle/soapserver/tutorial/associative_array.html for the documentation.

@francisbesset
Copy link
Member

It's okay? It's work?

This issue can be closed?

@guitoon
Copy link

guitoon commented Dec 2, 2013

Hi,
I try to update an existing Soap WebService using this bundle, but i need to replace "item" name for sequences by a custom name (defferent for each sequence).
So http://besim.pl/SoapBundle/soapserver/tutorial/associative_array.html isn't enough for me.
I found where item key is defined and used, but is it necessary?

Thanks

@rackberg
Copy link

"I try to update an existing Soap WebService using this bundle, but i need to replace "item" name for sequences by a custom name", from guitoon

Is there a way to get rid of the "item" tags?

Thanks

@francisbesset
Copy link
Member

Currently it's not possible to custom the "item" tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants