0
<?php  require_once "app/Mage.php";

    Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));
    $installer = new Mage_Sales_Model_Mysql4_Setup;
    // change details below:
    $attribute  = array(
        'type' => 'int',
        'label'=> 'IceCatID',
        'input' => 'text',
        'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
        'visible' => true,
        'required' => false,
        'user_defined' => true,
        'default' => "",
        'group' => "General Information"
    );
    $installer->addAttribute('catalog_category', 'IceCatID', $attribute);
    $installer->endSetup();?>

I created Custom attribute for category it's working fine but how to get api in this custom attribute we are developing Android App.

  • can you telll me you are need which api method only category list or info??? – Abdul Jan 25 '16 at 10:46
  • Let us assume i have one text box i set 0 i want to get that 0 in api also – Magento 2 Jan 25 '16 at 11:16
  • @Kothari,Which api you are using? – Amit Bera Jan 26 '16 at 7:40
  • Soap api using in andriod team – Magento 2 Jan 26 '16 at 8:16
8
+25

If you're using the SOAP Api try this:

  • Create a basic custom module and ensure that has <Mage_Catalog/> as dependency

Then add an api config file for overwrite the "category" complex types definitions:

app/code/{pool}/{vendor}/{module}/etc/wsdl.xml

And add this contents:

<?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">
        <complexType name="catalogCategoryEntity">
            <all>
                <element name="category_id" type="xsd:int"/>
                <element name="parent_id" type="xsd:int"/>
                <element name="name" type="xsd:string"/>
                <element name="is_active" type="xsd:int"/>
                <element name="position" type="xsd:int"/>
                <element name="level" type="xsd:int"/>
                <element name="children" type="typens:ArrayOfCatalogCategoryEntities"/>

                <!-- ADD YOUR ATTRIBUTE TO ANY DESIRED NODE -->
                <!-- CUSTOM ATTRIBUTE -->  
                <element name="ice_cat_id" type="xsd:int"/>
                <!-- CUSTOM ATTRIBUTE -->

            </all>
        </complexType>
        <complexType name="catalogCategoryEntityNoChildren">
            <all>
                <element name="category_id" type="xsd:int"/>
                <element name="parent_id" type="xsd:int"/>
                <element name="name" type="xsd:string"/>
                <element name="is_active" type="xsd:int"/>
                <element name="position" type="xsd:int"/>
                <element name="level" type="xsd:int"/>
            </all>
        </complexType>
        <complexType name="ArrayOfCatalogCategoryEntitiesNoChildren">
            <complexContent>
                <restriction base="soapenc:Array">
                    <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogCategoryEntityNoChildren[]"/>
                </restriction>
            </complexContent>
        </complexType>
        <complexType name="catalogCategoryTree">
            <all>
                <element name="category_id" type="xsd:int"/>
                <element name="parent_id" type="xsd:int"/>
                <element name="name" type="xsd:string"/>
                <element name="position" type="xsd:int"/>
                <element name="level" type="xsd:int"/>
                <element name="children" type="typens:ArrayOfCatalogCategoryEntities"/>
            </all>
        </complexType>
        <complexType name="catalogCategoryEntityCreate">
            <all>
                <element name="name" type="xsd:string" minOccurs="0"/>
                <element name="is_active" type="xsd:int" minOccurs="0"/>
                <element name="position" type="xsd:int" minOccurs="0"/>
                <!-- position parameter is deprecated, category anyway will be positioned in the end of list
                    and you can not set position directly, use catalog_category.move instead -->
                <element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0"/>
                <element name="custom_design" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_apply" type="xsd:int" minOccurs="0"/>
                <element name="custom_design_from" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_to" type="xsd:string" minOccurs="0"/>
                <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
                <element name="default_sort_by" type="xsd:string" minOccurs="0"/>
                <element name="description" type="xsd:string" minOccurs="0"/>
                <element name="display_mode" type="xsd:string" minOccurs="0"/>
                <element name="is_anchor" type="xsd:int" minOccurs="0"/>
                <element name="landing_page" type="xsd:int" minOccurs="0"/>
                <element name="meta_description" type="xsd:string" minOccurs="0"/>
                <element name="meta_keywords" type="xsd:string" minOccurs="0"/>
                <element name="meta_title" type="xsd:string" minOccurs="0"/>
                <element name="page_layout" type="xsd:string" minOccurs="0"/>
                <element name="url_key" type="xsd:string" minOccurs="0"/>
                <element name="include_in_menu" type="xsd:int" minOccurs="0"/>
            </all>
        </complexType>
        <complexType name="catalogCategoryInfo">
            <all>
                <element name="category_id" type="xsd:string"/>
                <element name="is_active" type="xsd:int"/>
                <element name="position" type="xsd:string"/>
                <element name="level" type="xsd:string"/>
                <element name="parent_id" type="xsd:string"/>
                <element name="all_children" type="xsd:string"/>
                <element name="children" type="xsd:string"/>
                <element name="created_at" type="xsd:string" minOccurs="0"/>
                <element name="updated_at" type="xsd:string" minOccurs="0"/>
                <element name="name" type="xsd:string" minOccurs="0"/>
                <element name="url_key" type="xsd:string" minOccurs="0"/>
                <element name="description" type="xsd:string" minOccurs="0"/>
                <element name="meta_title" type="xsd:string" minOccurs="0"/>
                <element name="meta_keywords" type="xsd:string" minOccurs="0"/>
                <element name="meta_description" type="xsd:string" minOccurs="0"/>
                <element name="path" type="xsd:string" minOccurs="0"/>
                <element name="url_path" type="xsd:string" minOccurs="0"/>
                <element name="children_count" type="xsd:int" minOccurs="0"/>
                <element name="display_mode" type="xsd:string" minOccurs="0"/>
                <element name="is_anchor" type="xsd:int" minOccurs="0"/>
                <element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0"/>
                <element name="custom_design" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_apply" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_from" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_to" type="xsd:string" minOccurs="0"/>
                <element name="page_layout" type="xsd:string" minOccurs="0"/>
                <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
                <element name="default_sort_by" type="xsd:string" minOccurs="0"/>
                <element name="landing_page" type="xsd:int" minOccurs="0"/>
            </all>
        </complexType>
    </schema>
  </types>
</definitions>

This is the full list of all category related nodes/actions so add your attribute to any of them. (I just added it to catalogCategoryEntity)

NOTES

  • By convention your attribute code should be ice_cat_id instead IceCatID you can still using "IceCatID" for label.
  • Keep just the modified <complex type>nodes in your wsdl file.
  • Clean Config/WSDL Cache(s) and if you don't see the changes just restart php to flush php wsdl cache.

EDIT: About WSDL Definition in Magento To clarify some concept:

We are using the WSDL Configuration to update <complexType> definitions. Every <complexType> node defines a data type that isn't standard (like 'int')

Every SOAP call has it own definition, if you make a call to catalogCategoryInfo: you will get a response body with a node called 'info' as defined here:

app/code/core/Mage/Catalog/etc/wsdl.xml

    ...
    <message name="catalogCategoryInfoRequest">
        <part name="sessionId" type="xsd:string"/>
        <part name="categoryId" type="xsd:int"/>
        <part name="storeView" type="xsd:string"/>
        <part name="attributes" type="typens:ArrayOfString"/>
    </message>
    <message name="catalogCategoryInfoResponse">
        <part name="info" type="typens:catalogCategoryInfo"/>
    </message>
    ...

This Service definition is telling us that requests to catalogCategoryInfo will give us a node called "info" of the catalogCategoryInfo type. This means that if you need your custom attribute for that call (catalogCategoryInfo) you have to add your attribute to the type definition (in your module wsdl.xml file):

app/code/{pool}/{vendor}/{module}/etc/wsdl.xml (part)

        ...
        <complexType name="catalogCategoryInfo">
            <all>
                <!-- MY CUSTOM ATTRIBUTE -->
                <element name="ice_cat_id" type="xsd:int"/>
                <!-- MY CUSTOM ATTRIBUTE -->
                <element name="category_id" type="xsd:string"/>
                <element name="is_active" type="xsd:int"/>
                <element name="position" type="xsd:string"/>
                <element name="level" type="xsd:string"/>
                <element name="parent_id" type="xsd:string"/>
                <element name="all_children" type="xsd:string"/>
                <element name="children" type="xsd:string"/>
                <element name="created_at" type="xsd:string" minOccurs="0"/>
                <element name="updated_at" type="xsd:string" minOccurs="0"/>
                <element name="name" type="xsd:string" minOccurs="0"/>
                <element name="url_key" type="xsd:string" minOccurs="0"/>
                <element name="description" type="xsd:string" minOccurs="0"/>
                <element name="meta_title" type="xsd:string" minOccurs="0"/>
                <element name="meta_keywords" type="xsd:string" minOccurs="0"/>
                <element name="meta_description" type="xsd:string" minOccurs="0"/>
                <element name="path" type="xsd:string" minOccurs="0"/>
                <element name="url_path" type="xsd:string" minOccurs="0"/>
                <element name="children_count" type="xsd:int" minOccurs="0"/>
                <element name="display_mode" type="xsd:string" minOccurs="0"/>
                <element name="is_anchor" type="xsd:int" minOccurs="0"/>
                <element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0"/>
                <element name="custom_design" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_apply" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_from" type="xsd:string" minOccurs="0"/>
                <element name="custom_design_to" type="xsd:string" minOccurs="0"/>
                <element name="page_layout" type="xsd:string" minOccurs="0"/>
                <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
                <element name="default_sort_by" type="xsd:string" minOccurs="0"/>
                <element name="landing_page" type="xsd:int" minOccurs="0"/>
            </all>
        </complexType>
        ...

Looking at the app/code/core/Mage/Catalog/etc/wsdl.xmlfile you will find which <compleType> definition node must edit for each message (When I say "add your attribute to every needed node" means that). So the workaround to do it would be something like that:

  1. Determine which SOAP service I need to consume.
  2. Find that service response definition in app/code/core/Mage/Catalog/etc/wsdl.xml
  3. Look at that definition and Find which node I need to modify.
  4. Use our app/code/{pool}/{vendor}/{module}/etc/wsdl.xml file to overwrite the definition (adding our custom attribute(s) there).
  5. Clean Magento Cache
  6. Clean Php Wsdl cache (or simply restart php service)

Note that the same workaround could be used if you want to remove some unused attributes to perform fastest requests.

EDIT 2: Missing Attributes for some methods

I forgot to mention that for some API methods the WSDL definition rewrite isn't enough. these methods are:

  • catalogCategoryTree

  • catalogCategoryLevel

In both cases the category data is actually loaded by collection so you need to rewrite these methods in order to get your custom attribute available in the response.

To add an attribute to the catalogCategoryTree API method

First we have to overwrite the Mage_Catalog_Model_Category_Api::tree method:

public function tree($parentId = null, $store = null)
{
    if (is_null($parentId) && !is_null($store)) {
        $parentId = Mage::app()->getStore($this->_getStoreId($store))->getRootCategoryId();
    } elseif (is_null($parentId)) {
        $parentId = 1;
    }

    /* @var $tree Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Tree */
    $tree = Mage::getResourceSingleton('catalog/category_tree')
        ->load();

    $root = $tree->getNodeById($parentId);

    if($root && $root->getId() == 1) {
        $root->setName(Mage::helper('catalog')->__('Root'));
    }

    $collection = Mage::getModel('catalog/category')->getCollection()
        ->setStoreId($this->_getStoreId($store))
        ->addAttributeToSelect('name')
        ->addAttributeToSelect('is_active')
        // Custom Attribute
        ->addAttributeToSelect('ice_cat_id');

    $tree->addCollectionData($collection, true);

    return $this->_nodeToArray($root);
}

Then we need to modify the Mage_Catalog_Model_Category_Api::_nodeToArray method too since return data is hardcoded:

protected function _nodeToArray(Varien_Data_Tree_Node $node)
{
    // Only basic category data
    $result = array();
    $result['category_id'] = $node->getId();
    $result['parent_id']   = $node->getParentId();
    $result['name']        = $node->getName();
    $result['is_active']   = $node->getIsActive();
    $result['position']    = $node->getPosition();
    $result['level']       = $node->getLevel();
    $result['children']    = array();

    // Custom Attribute
    $result['ice_cat_id']  = $node->getIceCatId();

    foreach ($node->getChildren() as $child) {
        $result['children'][] = $this->_nodeToArray($child);
    }

    return $result;
}

To add an attribute to the catalogCategoryLevel API method

We need to modify the Mage_Catalog_Model_Category_Api::level

public function level($website = null, $store = null, $categoryId = null)
{
    $ids = array();
    $storeId = Mage_Catalog_Model_Category::DEFAULT_STORE_ID;

    // load root categories of website
    if (null !== $website) {
        try {
            $website = Mage::app()->getWebsite($website);
            if (null === $store) {
                if (null === $categoryId) {
                    foreach ($website->getStores() as $store) {
                        /* @var $store Mage_Core_Model_Store */
                        $ids[] = $store->getRootCategoryId();
                    }
                } else {
                    $ids = $categoryId;
                }
            } elseif (in_array($store, $website->getStoreIds())) {
                $storeId = Mage::app()->getStore($store)->getId();
                $ids = (null === $categoryId)? $store->getRootCategoryId() : $categoryId;
            } else {
                $this->_fault('store_not_exists');
            }
        } catch (Mage_Core_Exception $e) {
            $this->_fault('website_not_exists', $e->getMessage());
        }
    }
    elseif (null !== $store) {
        // load children of root category of store
        if (null === $categoryId) {
            try {
                $store = Mage::app()->getStore($store);
                $storeId = $store->getId();
                $ids = $store->getRootCategoryId();
            } catch (Mage_Core_Model_Store_Exception $e) {
                $this->_fault('store_not_exists');
            }
        }
        // load children of specified category id
        else {
            $storeId = $this->_getStoreId($store);
            $ids = (int)$categoryId;
        }
    }
    // load all root categories
    else {
        $ids = (null === $categoryId)? Mage_Catalog_Model_Category::TREE_ROOT_ID : $categoryId;
    }

    $collection = Mage::getModel('catalog/category')->getCollection()
        ->setStoreId($storeId)
        ->addAttributeToSelect('name')
        ->addAttributeToSelect('is_active')
        // ---
        // CUSTOM ATTRIBUTE
        ->addAttributeToSelect('ice_cat_id');

    if (is_array($ids)) {
        $collection->addFieldToFilter('entity_id', array('in' => $ids));
    } else {
        $collection->addFieldToFilter('parent_id', $ids);
    }

    // Only basic category data
    $result = array();
    foreach ($collection as $category) {
        /* @var $category Mage_Catalog_Model_Category */
        $result[] = array(
            'category_id' => $category->getId(),
            'parent_id'   => $category->getParentId(),
            'name'        => $category->getName(),
            'is_active'   => $category->getIsActive(),
            'position'    => $category->getPosition(),
            'level'       => $category->getLevel()
            // ---
            // CUSTOM ATTRIBUTE
            'ice_cat_id'  => $category->getIceCatId()
        );
    }

    return $result;
}

Alternatively you can overwrite hook the event catalog_category_collection_save_after and add your attribute by default every time the collection is loaded but you will still need to change the _nodeToArray() and level methods.

  • Good attempt @MauroNigrele – Amit Bera Jan 26 '16 at 7:42
  • @AmitBera thanks! is actually a "working example" i did it that way several times. – MauroNigrele Jan 26 '16 at 7:48
  • Can i use this ice_cat_id or IceCatID. can you please update that working module – Magento 2 Jan 26 '16 at 15:08
  • @kothari which part? – MauroNigrele Jan 26 '16 at 15:21
  • we used IceCatID for all place(wsdl.xml & api.php) after that i got null value only that what i am asking can you please update that module or i need to use ice_cat_id for all – Magento 2 Jan 26 '16 at 15:26
-1

Accessing and new value from API has following steps

1) Create attribute from magento admin or through magento setup script 2) define the attribute in wsdl , now you have two thing i.e request and response 2.1) For request part you can put the value in Mage/Catalog/etc/wsdl.xml

Ex: The following is sample for Request,if you have already have wsdl.xml in your module which is preferred

    <!-- CUSTOM ATTRIBUTE -->  
            <element name="IceCatID" type="xsd:int"/>
            <!-- CUSTOM ATTRIBUTE -->

                <element name="children" type="typens:ArrayOfCatalogCategoryEntities"/>
            </all>
        </complexType>

Clear the cache and type you wsdl url in browser to see if the new attribute is showing up under catalogCategoryEntity, which mean you now have given provision to transfer data between two systems

3) Once you are done with step2, now you need to go to api.php in you module ,usually at your_module/model/api.php or whatever the model you have setup in your_module/et/api.xml

4) Go to respective method which you have mapped in api.xml

Ex:

public function create($categoryData) { //To see what values are there var_dump($categoryData);

    /** @var $category Mage_Catalog_Model_Category */
 $category = Mage::getModel('catalog/category')
        ->setStoreId(0)
        ->load($categoryData['category_id']);

$category->setData('IceCatID','your value for IceCatID');

}

you can refer http://code.tutsplus.com/tutorials/create-a-custom-api-in-magento-part-one--cms-23785 for Custom module for API

Hope this helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.