Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento API: Publish a new method in soap V2

Tags:

soap

api

magento

I'm new in Magento and I'd like to create a my own API v2 method. I've built a simple project...

Mycompany
    Mymodule
        etc
            api.xml
            config.xml
            wsdl.xml
        Model
            Api
                V2.php
            Api.php


These are the main files...
(1) api.xml

<config>
    <api>
        <resources>
            <mymodule translate="title" module="mymodule">
                <title>mymodule</title>
                <model>mymodule/api</model>
                <methods>                    
                    <myapimethod translate="title" module="mymodule">
                        <title>myapimethod</title>
                        <acl>mymodule/myapimethod</acl>
                    </myapimethod>
                </methods>
            </mymodule>
        </resources>
        <v2>
            <resources_function_prefix>
                <mymodule>mymodule</mymodule>
            </resources_function_prefix>
        </v2>
        <acl>
            <resources>
                <mymodule translate="title" module="mymodule">
                    <title>Mymodule</title>
                    <sort_order>2000</sort_order>                    
                    <myapimethod translate="title" module="mymodule">
                        <title>myapimethod</title>
                    </myapimethod>  
                </mymodule>
            </resources>
        </acl>
    </api>
</config>

(2) wsdl.xml

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
        </schema>
    </types>
    <message name="myapimethodRequest">
        <part name="sessionId" type="xsd:string"/>
        <part name="message" type="xsd:string" />
    </message>
    <message name="myapimethodResponse">
        <part name="result" type="xsd:string" />
    </message>
    <portType name="{{var wsdl.handler}}PortType">
        <operation name="myapimethod">
            <documentation>this is an example of api method...</documentation>
            <input message="typens:myapimethodRequest" />
            <output message="typens:myapimethodResponse" />
        </operation>
    </portType>
    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="myapimethod">
            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
            <input>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </input>
            <output>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </output>
        </operation>
    </binding>
    <service name="{{var wsdl.name}}Service">
        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
            <soap:address location="{{var wsdl.url}}" />
        </port>
    </service>
</definitions>

(3) Api.php

<?php
class Mycompany_Mymodule_Model_Api extends Mage_Api_Model_Resource_Abstract
{        
        public function myapimethod($sessionId, $message)
        {
            return "This is the message : ".$message;
        }
}

(4) V2.php

<?php
class Mycompany_Mymodule_Model_Api_V2 extends Mycompany_Mymodule_Model_Api
{        

}

(5) test.php

<?php
try {
    define("SOAP_WSDL",'http://localhost:8080/magento/index.php/api/?wsdl');
    define("SOAP_WSDL2",'http://localhost:8080/magento/index.php/api/v2_soap?wsdl=1');
    define("SOAP_USER","dtsSoapUser");
    define("SOAP_PASS","casares");

    if($_GET['ver'] == '2') {
        $client = new SoapClient(SOAP_WSDL2, array('trace' => 1,'cache_wsdl' => 0));
        echo "<br>version 2 <br>";
    }
    else {
        $client = new SoapClient(SOAP_WSDL,array('trace' => 1,'cache_wsdl' => 0));

        echo "<br>version 1 <br>";
    }
    $session = $client->login(SOAP_USER, SOAP_PASS);
    $result = array();

    try {
        if($_GET['ver'] == '2') {
             $result = $client->Myapimethod($session, "My message....");
             var_dump ( $result);        
        } else {            
            $result= $client->call($session, 'mymodule.myapimethod', array($session, "My message ...."));
            var_dump($result);
        }
    } catch (SoapFault $exception) {
        echo 'EXCEPTION='.$exception;
    }

    echo "<br>end test<br>";
} catch (Exception $e){
    echo var_dump($e);
    throw $e;
}   
?>

Using the following Url, the result is:

.../test.php/?ver=1

version 1
string 'This is the message : My message ....' (length=37)
end test

It's to say: using Soap v1, the method works!.

But if I use the soap v2 call...

.../test.php/?ver=2 the result is:

version 2
EXCEPTION=SoapFault exception: [3] Invalid api path. in C:\wamp\www\PruebasPHP\test.php:22 Stack trace: #0 C:\wamp\www\PruebasPHP\test.php(22): SoapClient->__call('Myapimethod', Array) #1 C:\wamp\www\PruebasPHP\test.php(22): SoapClient->Myapimethod('b9e1e8d15a61398...', 'My message....') #2 {main}
end test


The role has access to all the api resources...

I don't know what is wrong? can anyone help me with this problem? Can be anything related to acl's? Thanks in advance!!!

like image 906
Juanma R. Avatar asked Aug 29 '12 06:08

Juanma R.


2 Answers

It's a problem of path.
I've solve the problems as follows...
The folder structure of my project is:

Mycompany->
    Mymodule->
        etc->
            api.xml
            config.xml
            wsdl.xml
            wsi.xml
        Model->
            Folder->
                Api.php
                Api->
                    V2.ph

(1) api.xml

<?xml version="1.0"?>
<config>
    <api>
        <resources>
            <mymodule_folder translate="title" module="mymodule">
                <title>mymodule</title>
                <!-- acl>mymodule/api</acl>-->
                <model>mymodule/folder_api</model>
                <acl>mymodule/folder</acl>
                <methods>                    
                    <myapimethod translate="title" module="mymodule">
                        <title>myapimethod</title>
                        <acl>mymodule/folder/myapimethod</acl>
                    </myapimethod> 
                </methods>
            </mymodule_folder>
        </resources>
        <resources_alias>
            <folder>mymodule_folder</folder>
         </resources_alias>

        <v2>
            <resources_function_prefix>
                <folder>folder</folder>
            </resources_function_prefix>
        </v2>
        <acl>
            <resources>
                <mymodule translate="title" module="mymodule">
                    <title>mymodule</title>
                    <sort_order>1</sort_order>
                    <folder translate="title" module="mymodule">
                        <title>Folder</title>
                        <sort_order>2000</sort_order>                    
                <myapimethod translate="title" module="mymodule">
                            <title>myapimethod</title>
                        </myapimethod>  
                    </folder>
             </mymodule>
            </resources>
        </acl>
    </api>
</config>

Pay attention to the name of the api method "myapimethod" and the folder "Model\Folder".

(2) wsdl.xml

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
        </schema>
    </types>
    <message name="folderMyapimethodRequest">
        <part name="sessionId" type="xsd:string"/>
        <part name="message" type="xsd:string" />
    </message>
    <message name="folderMyapimethodResponse">
        <part name="result" type="xsd:string" />
    </message>
    <portType name="{{var wsdl.handler}}PortType">
        <operation name="folderMyapimethod">
            <documentation>this is an example of api method...</documentation>
            <input message="typens:folderMyapimethodRequest" />
            <output message="typens:folderMyapimethodResponse" />
        </operation>
    </portType>
    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="folderMyapimethod">
            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
            <input>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </input>
            <output>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </output>
        </operation>
    </binding>
    <service name="{{var wsdl.name}}Service">
        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
            <soap:address location="{{var wsdl.url}}" />
        </port>
    </service>
</definitions> 

The name of the api method must be: folderMethodname", where "folder" is the name of the folder under the "Model" where the api method is declared.., in our case : "folderMyapimethod"
(3) api.php

<?php
class Mycompany_Mymodule_Model_Folder_Api extends Mage_Api_Model_Resource_Abstract
{        
        public function myapimethod( $message)
        {
            return "This is the message: ".$message;
        }
}

(4) V2.php

<?php
class Mycompany_Mymodule_Model_Folder_Api_V2 extends Mycompany_Mymodule_Model_Folder_Api
{   
     //empty     
}


(5) test.php

$result = $client->folderMyapimethod($session,$message);

This line shows how to call to my api method...

It works!

like image 106
Juanma R. Avatar answered Oct 28 '22 05:10

Juanma R.


Your code is excellent ! there's no mistake on

As far as i know (from my experience). that exception shown because your tag placement on your api.xml doesn't match with you called function.


check on files

core\Mage\Catalog\Model\Product\Api.php

and

core\Mage\Catalog\Model\Product\Api\V2.php

there is a function named items on both class.

maybe you must add your code on api_v1 on api_v2 class like this:

<?php
class Mycompany_Mymodule_Model_Api_V2 extends Mycompany_Mymodule_Model_Api
{        
    public function myapimethod($sessionId, $message)
    {
        return "This is the message : ".$message;
    }
}

or

maybe it's cache.

The cache is strong, because it's API V2. try to clear your cache on:

  1. admin -> system -> cache management -> clear magento cache.
  2. try to clear wsdl.xml cache on /tmp/wsdl.xml (hidden on your server) try to grep it.
  3. remove all files on var/log/*
like image 24
Josua Marcel C Avatar answered Oct 28 '22 03:10

Josua Marcel C