2014-02-18 3 views
5

Ich habe versucht, die REST-API von Magento zu erweitern, um konfigurierbares Produkt hinzuzufügen, aber ich liefere den Fehler 405 - Resource Method Not Implemented.Magento REST API Create-Methode - Ressourcenmethode nicht implementiert

Das ist mein api.xml:

<?xml version="1.0"?> 
<config> 
    <api2> 
     <resource_groups> 
      <extapi translate="title" module="api2"> 
       <title>Magepim API calls</title> 
       <sort_order>30</sort_order> 
       <children> 
        <extapi_product translate="title" module="api2"> 
         <title>Product</title> 
         <sort_order>50</sort_order> 
        </extapi_product> 
       </children> 
      </extapi> 
     </resource_groups> 
     <resources> 
      <extapiproducts translate="title" module="api2"> 
       <group>extapi_product</group> 
       <model>extapi/catalog_api2_product</model> 
       <working_model>extapi/catalog_api2_product</working_model> 
       <title>Catalog Product</title> 
       <sort_order>10</sort_order> 
       <privileges> 
        <admin> 
         <create>1</create> 
         <retrieve>1</retrieve> 
         <update>1</update> 
         <delete>1</delete> 
        </admin> 
       </privileges> 
       <attributes translate="product_count" module="api2"> 
        <product_count>Product Count</product_count> 
        <catalog_size>Product Count</catalog_size> 
       </attributes> 
       <entity_only_attributes> 
        <catalog> 
         <read> 
          <has_custom_options>1</has_custom_options> 
          <tier_price>1</tier_price> 
          <total_reviews_count>1</total_reviews_count> 
          <url>1</url> 
          <buy_now_url>1</buy_now_url> 
          <has_custom_options>1</has_custom_options> 
          <is_in_stock>1</is_in_stock> 

         </read> 
        </catalog> 
        </entity_only_attributes> 
       <exclude_attributes> 
        <catalog> 
         <read> 
          <attribute_set_id>1</attribute_set_id> 
          <stock_data>1/</stock_data> 
          <use_config_gift_message_available>1</use_config_gift_message_available> 
          <use_config_gift_wrapping_available>1</use_config_gift_wrapping_available> 
          <url_key_create_redirect>1</url_key_create_redirect> 

         </read> 
        </catalog> 
        <admin> 
         <read> 
          <product_count>1</product_count> 
         </read> 
        </admin> 
       </exclude_attributes> 
       <routes> 
        <route_entity_count> 
         <route>/magepim/products</route> 
         <action_type>entity</action_type> 
        </route_entity_count> 
       </routes> 
       <versions>1</versions> 
      </extapiproducts> 
     </resources> 
    </api2> 
</config> 

und das ist mein V1.php:

<?php 

/** 
* Override for Magento's Catalog REST API 
*/ 
class Magepim_Extapi_Model_Catalog_Api2_Product_Rest_Admin_V1 extends Mage_Catalog_Model_Api2_Product_Rest { 

    /** 
    * Retrieves the catalog collection and returns it's size 
    * 
    * @return int 
    */ 

    protected function _retrieve() 
    { 
     /** @var $collection Mage_Catalog_Model_Resource_Product_Collection */ 
     $collection = Mage::getResourceModel('catalog/product_collection'); 
     $store = $this->_getStore(); 
     $collection->setStoreId($store->getId()); 
     $collection->addAttributeToSelect(array_keys(
       $this->getAvailableAttributes($this->getUserType(), Mage_Api2_Model_Resource::OPERATION_ATTRIBUTE_READ) 
     )); 
     $this->_applyCategoryFilter($collection); 
     $this->_applyCollectionModifiers($collection); 
     $products = $collection->load()->toArray(); 
     $size = $collection->getSize(); 
     $productCount = new stdClass(); 
     $productCount->catalog_size=$size; 
     //return $size; 
     return json_encode($productCount); 
    } 

    protected function _create($data) 
    { 
     /* @var $validator Mage_Catalog_Model_Api2_Product_Validator_Product */ 
     $validator = Mage::getModel('catalog/api2_product_validator_product', array(
      'operation' => self::OPERATION_CREATE 
     )); 

     if (!$validator->isValidData($data)) { 
      foreach ($validator->getErrors() as $error) { 
       $this->_error($error, Mage_Api2_Model_Server::HTTP_BAD_REQUEST); 
      } 
      $this->_critical(self::RESOURCE_DATA_PRE_VALIDATION_ERROR); 
     } 

     $type = $data['type_id']; 
     if ($type !== 'simple') { 
      $this->_critical("Creation of products with type '$type' is not implemented", 
       Mage_Api2_Model_Server::HTTP_METHOD_NOT_ALLOWED); 
     } 
     $set = $data['attribute_set_id']; 
     $sku = $data['sku']; 

     /** @var $product Mage_Catalog_Model_Product */ 
     $product = Mage::getModel('catalog/product') 
      ->setStoreId(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID) 
      ->setAttributeSetId($set) 
      ->setTypeId($type) 
      ->setSku($sku); 

     foreach ($product->getMediaAttributes() as $mediaAttribute) { 
      $mediaAttrCode = $mediaAttribute->getAttributeCode(); 
      $product->setData($mediaAttrCode, 'no_selection'); 
     } 

     $this->_prepareDataForSave($product, $data); 
     try { 
      $product->validate(); 
      $product->save(); 
      $this->_multicall($product->getId()); 
     } catch (Mage_Eav_Model_Entity_Attribute_Exception $e) { 
      $this->_critical(sprintf('Invalid attribute "%s": %s', $e->getAttributeCode(), $e->getMessage()), 
       Mage_Api2_Model_Server::HTTP_BAD_REQUEST); 
     } catch (Mage_Core_Exception $e) { 
      $this->_critical($e->getMessage(), Mage_Api2_Model_Server::HTTP_INTERNAL_ERROR); 
     } catch (Exception $e) { 
      $this->_critical(self::RESOURCE_UNKNOWN_ERROR); 
     } 

     return $this->_getLocation($product); 
    } 

    protected function _multicreate($data) 
    { 
     $this->getResponse()->addMessage ("", 0, array (
      'result' => "created" 
     ), Mage_Api2_Model_Response::MESSAGE_TYPE_SUCCESS); 
     $this->getResponse()->setRawHeader ('"Content-Type" = "application/json"'); 
     $base_url = Mage::getBaseUrl (Mage_Core_Model_Store::URL_TYPE_WEB); 
     $base_url = substr ($base_url, 0, strlen ($base_url) - 1); 
     return $base_url . $this->_getLocation ($order); 
    } 

    protected function _update(array $data) 
    { 
     return json_encode($productCount); 
    } 

    protected function _delete() 
    { 
     $this->getResponse()->addMessage ("", 0, array (
      'result' => "deleted" 
     ), Mage_Api2_Model_Response::MESSAGE_TYPE_SUCCESS); 
     return json_encode(array("result","_delete")); 
    } 
} 

In diesem Stadium

<?xml version="1.0"?> 
<config> 
    <api> 
     <resources> 
      <extapi_catalog translate="title" module="extapi"> 
       <model>extapi/catalog_api2</model> 
       <title>Extapi Catalog API</title> 
       <acl>extapi/product</acl> 
       <methods> 
        <list translate="title" module="extapi"> 
         <title>Retrieve Product Count</title> 
         <method>count</method> 
         <acl>extapi/product/info</acl> 
        </list> 
        <create translate="title" module="extapi"> 
         <title>Create products</title> 
         <acl>extapi/product/create</acl> 
        </create> 
        <update translate="title" module="extapi"> 
         <title>Update products</title> 
         <method>update</method> 
         <acl>extapi/product/update</acl> 
        </update> 
        <delete translate="title" module="extapi"> 
         <title>Delete products</title> 
         <method>delete</method> 
         <acl>extapi/product/delete</acl> 
        </delete> 
       </methods> 
       <faults module="extapi"> 
        <data_invalid> 
         <code>100</code> 
         <message>Invalid Request. Details in error message.</message> 
        </data_invalid> 
        <filters_invalid> 
         <code>101</code> 
         <message>Invalid filters specified. Details in error message.</message> 
        </filters_invalid> 
        <not_exists> 
         <code>102</code> 
         <message>No products.</message> 
        </not_exists> 
        <not_deleted> 
         <code>103</code> 
         <message>Product not deleted. Details in error message.</message> 
        </not_deleted> 
       </faults> 
      </extapi_catalog> 
     </resources> 
     <v2> 
      <resources_function_prefix> 
       <extapi_catalog>extapi_catalog</extapi_catalog> 
      </resources_function_prefix> 
     </v2> 

     <acl> 
      <resources> 
       <extapi_catalog translate="title" module="extapi"> 
        <title>Catalog</title> 
        <sort_order>3</sort_order> 
        <info translate="title" module="extapi"> 
         <title>Retrieve product count</title> 
        </info> 
        <create translate="title" module="extapi"> 
         <title>Create product count</title> 
        </create> 
        <update translate="title" module="extapi"> 
         <title>Update product count</title> 
        </update> 
        <delete translate="title" module="extapi"> 
         <title>Delete product count</title> 
        </delete> 
       </extapi_catalog> 
      </resources> 
     </acl> 
    </api> 
</config> 

dies mein api2.xml ist , _retrieve() ist die einzige Methode, die ordnungsgemäß funktioniert. Das _delete() scheint in der Lage zu sein, Methodenaufruf und Rückgabecode 200 zu empfangen. _update() scheint den Methodenaufruf ordnungsgemäß zu empfangen, obwohl ein Codierungsfehler zurückgegeben wird.

Mein Hauptproblem ist die _create(), die überhaupt nicht aufgerufen wird. Selbst wenn ich alle Anweisungen in der Methode (die aus /app/Mage/Model/Api2/Product/Rest/AdminV1.php kopiert wurde) lösche, bleibt das Problem bestehen.

Kann mir bitte jemand einen Rat geben? Gibt es auch eine Dokumentation, die für die Erweiterung der REST API (nicht Core API) verfügbar ist? Ich habe ein paar Tutorials im Web gefunden (mein Code wurde auf eines der Tutorials erweitert), aber keiner von ihnen gibt Details darüber an, was ein bestimmtes Tag in der api.xml/api2.xml bedeutet und wie das Methoden-Mapping sein sollte erledigt.

Vielen Dank im Voraus.

+1

Änderung ' Einheit' zu ' Sammlung' und es wird funktionieren ..... –

Antwort

7

Ich habe nicht viel mit Magento RESTish API gearbeitet, aber die

Ressourcen Methode noch nicht implementiert.

Fehlerstring wird in der folgenden Konstante

#File: app/code/core/Mage/Api2/Model/Resource.php 
const RESOURCE_METHOD_NOT_IMPLEMENTED = 'Resource method not implemented yet.'; 

definiert Diese Konstante verwendet wird, einen kritischen API-Fehler in den folgenden Orten

#File: app/code/core/Mage/Api2/Model/Resource.php 
public function dispatch() 
{ 
    switch ($this->getActionType() . $this->getOperation()) {  
     case self::ACTION_TYPE_ENTITY . self::OPERATION_CREATE: 
      // Creation of objects is possible only when working with collection 
      $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED); 
      break; 
     case self::ACTION_TYPE_COLLECTION . self::OPERATION_CREATE: 
      // If no of the methods(multi or single) is implemented, request body is not checked 
      if (!$this->_checkMethodExist('_create') && !$this->_checkMethodExist('_multiCreate')) { 
       $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED); 
      } 
     ... 
     default: 
      $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED); 
    } 
} 

... 

protected function _errorIfMethodNotExist($methodName) 
{ 
    if (!$this->_checkMethodExist($methodName)) { 
     $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED); 
    } 
} 

So zu erhöhen, einige Bildung nehme hier Vermutungen, Es sieht so aus, als ob dieser Fehler ausgelöst wird, wenn

  1. Sie versuchen, auf einer einzigen Einheit

  2. Sie befinden sich auf einer Sammlung erstellen zu nennen versuchen, erstellen zu rufen, und die _create oder _multiCreate Methoden auf Ihre PHP-Klasse nicht

  3. Sie versuchen, einen Anruf umgesetzt haben Methode, die nicht eine der kanonischen CRUD-Methoden ist (der Standardfall)

  4. Oder wenn der Magento Systemcode den geschützten _errorIfMethodNotExist Fehler aufruft.

Die _errorIfMethodNotExist ist viel, aber in Bezug auf _create Anrufe verwendet wird, ist es hier

#File: app/code/core/Mage/Api2/Model/Resource.php 
// The create action has the dynamic type which depends on data in the request body 
if ($this->getRequest()->isAssocArrayInRequestBody()) { 
    $this->_errorIfMethodNotExist('_create'); 
    $filteredData = $this->getFilter()->in($requestData); 
    if (empty($filteredData)) { 
     $this->_critical(self::RESOURCE_REQUEST_DATA_INVALID); 
    } 
    $newItemLocation = $this->_create($filteredData); 
    $this->getResponse()->setHeader('Location', $newItemLocation); 

Ich bin mir nicht ganz sicher, was das hier ist für verwendet. Vielleicht sind die obigen Kommentare für Sie sinnvoll (wenn Sie die REST-API verwenden).

Unabhängig davon, würde ich herausfinden, welcher dieser Aufrufe an _critical Trigger Ihren spezifischen Fehler (verwenden Sie einige Protokollierung), und das könnte Ihnen helfen, zu entschlüsseln, was mit Ihrem Code falsch ist.

Außerdem schrieb ich eine article series über die Implementierung der SOAP/XML-RPC API. Obwohl die REST-API neuen Code verwendet, der nicht mit SOAP/XML-RPC zu tun hat, kann diese Serie Ihnen dennoch einige Einblicke in die Implementierung der REST-API geben.

+0

Vielen Dank für Ihren Detailvorschlag. Ich würde mich definitiv darum kümmern, ob ich es zum Laufen bringen kann. – Eddie

Verwandte Themen