Magento REST API Create Method - Resource Method Not Implemented - php

I have been trying to extend the REST API of magento to add configurable product, but I run into the error 405 - Resource Method Not Implemented.
This is my api.xml:
<?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>
this is my api2.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>
and this is my 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"));
}
}
At this stage, _retrieve() is the only method that is working properly. The _delete() seems to be able to receive method call and return code 200. _update() also seems to receive method call properly even though it returns an encoding error.
My main problem is the _create(), which doesn't get called at all. Even I remove all the statements inside the method (which is copied from /app/Mage/Model/Api2/Product/Rest/AdminV1.php), the same problem persists.
Can anyone please give me some advice? Also, is that any documentation available for extending the REST api (not Core API)? I have found a few tutorials on the web (my code is extended to one of the tutorials), but none of them specify the details of what a particular tag in the api.xml/api2.xml means and how the method mapping should be done.
Thanks in advance.

I haven't worked much with Magento's RESTish API, but the
Resource method not implemented yet.
error string is defined in the following constant
#File: app/code/core/Mage/Api2/Model/Resource.php
const RESOURCE_METHOD_NOT_IMPLEMENTED = 'Resource method not implemented yet.';
This constant is used to raise a critical API error in the following locations
#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, taking some education guesses here, it looks like this error is thrown when
You attempt to call create on a single entity
You attempt to call create on a collection, and the _create or _multiCreate methods haven't been implemented on your PHP class
You attempt to call a method that's not one of the canonical CRUD methods (the default case)
Or if the Magento system code calls the protected _errorIfMethodNotExist error.
The _errorIfMethodNotExist is used a lot, but in relation to _create calls, it's used here
#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);
I'm not quite sure what this one's for. Maybe the comments above make sense to you (if you're used the REST API).
Regardless, I'd figure out which one of these calls to _critical is trigger your specific error (use some logging), and that might help you unravel what's wrong with your code.
Also, I wrote an article series on the implementation of the SOAP/XML-RPC API. Although the REST API uses new code not related to SOAP/XML-RPC, that series still may provide you with some insight on how the REST API is implemented.

Related

Magento 2 - Controller returning blank page

Been spending the last 1 day to find a fix for this.
Basically everything works normal if I delete all the contents of generated folder and then generate the files dynamically by accessing the pages rather than doing setup:di:compile.
On the production though, I'm forced to do setup:di:compile and I end up with this certain admin module page being empty.
This is the controller of the page:
namespace Eadesigndev\AWB\Controller\Adminhtml\Index;
use Eadesigndev\Awb\Api\AwbRepositoryInterface;
use Eadesigndev\Awb\Model\Awb;
use Eadesigndev\Awb\Model\AwbFactory;
use Eadesigndev\Awb\Helper\Data as DataHelper;
use Magento\Framework\Registry;
use Magento\Backend\App\Action\Context;
use Magento\Backend\Model\Session;
use Magento\Framework\View\Result\PageFactory;
use Magento\Backend\App\Action;
class Edit extends Action
{
/**
* Authorization level of a basic admin session
*
*
*/
const ADMIN_RESOURCE = 'Eadesigndev_Awb::awb';
protected $resultPageFactory;
private $awbRepository;
private $awbFactory;
private $registry;
private $session;
private $dataHelper;
private $awbModel;
public function __construct(
Context $context,
PageFactory $resultPageFactory,
AwbRepositoryInterface $awbRepository,
AwbFactory $awbFactory,
Awb $awbModel,
Registry $registry,
DataHelper $dataHelper
) {
$this->resultPageFactory = $resultPageFactory;
$this->awbRepository = $awbRepository;
$this->awbFactory = $awbFactory;
$this->registry = $registry;
$this->awbModel = $awbModel;
$this->session = $context->getSession();
$this->dataHelper = $dataHelper;
parent::__construct($context);
}
/**
* Edit action new awb.
*
* #return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
$id = $this->getRequest()->getParam('entity_id');
if ($id) {
$model = $this->awbRepository->getById($id);
if (!$model->getEntityId()) {
$this->messageManager->addErrorMessage(__('This field no longer exists.'));
/** \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create();
return $resultRedirect->setPath('*/*/');
}
} else {
echo '3';
$model = $this->awbFactory->create();
}
/** #var Session $data */
$data = $this->session->getFormData(true);
if (!empty($data)) {
$model->setData($data);
}
$this->registry->register('awb_data', $model);
echo 'wat';
/** #var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->addBreadcrumb(__('Edit new Awb'), __('Edit new Awb'));
$resultPage->getConfig()->getTitle()->prepend(__('Edit new Awb'));
echo 'pac';
return $resultPage;
}
the controller currently returns a blank page with my debug strings:
3watpac
in /vendor/eadesignro/awb/Block/Adminhtml/Xtea I have the next files:
Edit (folder)
Edit.php
EditAwb.php
in /vendor/eadesignro/awb/view/adminhtml/layout I have the next files:
shipping_awb_index_edit.xml
shipping_awb_index_editawb.xml
shipping_awb_index_index.xml
Content of shipping_awb_index_edit.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="editor"/>
<head></head>
<body>
<referenceContainer name="content">
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit" name="awb_edit"/>
</referenceContainer>
<referenceContainer name="left">
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit\Tabs" name="awb_edit_tabs">
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit\Tab\General" name="awb_edit_tab_general"/>
<action method="addTab">
<argument name="name" xsi:type="string">general_section</argument>
<argument name="block" xsi:type="string">awb_edit_tab_general</argument>
</action>
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit\Tab\Curier" name="awb_edit_tab_curier"/>
<action method="addTab">
<argument name="name" xsi:type="string">curier_section</argument>
<argument name="block" xsi:type="string">awb_edit_tab_curier</argument>
</action>
</block>
</referenceContainer>
</body>
</page>
This is the page:
magento_admin_secreturl/shipping_awb/index/edit/key/xxxxxx
these are the routers:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="shipping_awb" frontName="shipping_awb">
<module name="Eadesigndev_Awb" before="Magento_Backend"/>
</route>
<route id="edit_awb" frontName="edit_awb">
<module name="Eadesigndev_Awb" before="Magento_Backend"/>
</route>
</router>
</config>
Any possible idea on why $this->resultPageFactory->create(); is simply returning nothing on production but working on development?
The index page works both on production and dev without any problem.
I can provide more info if needed, thank you!
The problem was a CAPSLOCK mistake in the namespace.
namespace Eadesigndev\AWB\Controller\Adminhtml\Index;
should have been
namespace Eadesigndev\Awb\Controller\Adminhtml\Index;
notice the 'AWB' becoming 'Awb'.
Apparently in development mode, the namespaces are not case-sensitive? or perhaps they are all transformed to capslock. If anyone has a clue, leave a comment, thanks!
For anyone who is still getting a blank page in Admin Controller, but the alternative solutions (case-sensitive) doesn't work for you, you may try running php bin/magento setup:di:compile.
This helped me.

Magento Checkout, Trying to create a new module for free products

I'm triying to create a new module to bypass checkout process for free downloadable products. As I'm not a developer I need some help with xml files of module.
I've this folder structure:
app/etc/modules/Fe_Freecheckout.xml
app/code/local/Fe/Freecheckout/controllers/CheckoutController.php
app/code/local/Fe/Freecheckout/etc/config.xml
And these are the contents of files:
CheckoutController.php
<?php
public function purchaseAction() {
if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
$this->_redirectUrl(Mage::getBaseUrl().'customer/account');
return;
}
$request = $this->getRequest();
$id = $request->getParam('id');
$product = Mage::getModel('catalog/product')
->load($id)
->setStoreId(Mage::app()->getStore()->getId());
if(!($product->getIsVirtual() && $product->getFinalPrice() == 0)){
Mage::getSingleton('checkout/session')->addError($this->__('Method only available for Free Downloadable Items'));
return $this;
}
$onepage = Mage::getSingleton('checkout/type_onepage');
/* #var $onepage Mage_Checkout_Model_Type_Onepage */
try{
$quote = $onepage->getQuote();
/* #var $quote Mage_Sales_Model_Quote */
$quote->addProduct($product);
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
$onepage->initCheckout();
$payment=array('method'=>'free');
$onepage->savePayment($payment);
$onepage->saveOrder();
$this->getResponse()->setRedirect('/downloadable/customer/products');
}
catch(Exception $e){
$result = $e->getMessage();
Mage::getSingleton('checkout/session')->addError($result);
}
}
?>
app/etc/modules/Fe_Freecheckout.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Fe_Freecheckout>
<!-- Whether our module is active: true or false -->
<active>true</active>
<!-- Which code pool to use: core, community or local -->
<codePool>local</codePool>
</Fe_Freecheckout>
</modules>
</config>
And this is app/code/local/Fe/Freecheckout/etc/config.xml
where i don't know how register my checkout controller:
<?xml version="1.0" encoding="UTF-8"?>
<!-- The root node for Magento module configuration -->
<config>
<!--
The module's node contains basic
information about each Magento module
-->
<modules>
<!--
This must exactly match the namespace and module's folder
names, with directory separators replaced by underscores
-->
<Fe_Freecheckout>
<!-- The version of our module, starting at 0.0.1 -->
<version>0.0.1</version>
</Fe_Freecheckout>
</modules>
</config>
Then in product/view.phtml I use the following code to checkout:
<?php if($_product->isVirtual() && $_product->getFinalPrice()==0) { ?>
<?php echo $this->__('Download and Install') ?>
<?php } ?>
I always get a Page not Found...Any directions, please?
Thank you.
I think you need to override onepagecontroller
<global>
<rewrite>
<Packag_modulename_checkout_onepagecontroller>
<from><![CDATA[#^/checkout/onepage/#]]></from> <!-- Mage_Checkout_OnepageController -->
<to>/modulename/checkout_onepage/</to> <!-- Package_ModuleName_Checkout_OnepageController -->
</Package_modulename_checkout_onepagecontroller>
</rewrite>
<helpers>
<modulename>
<class>Package_ModuleName_Helper</class>
</modulename>
</helpers>
</global>
this might help you.

Magento custom REST API response in JSON

For Magento 1.9 I'm working on a module where I defined a custom REST route to retrieve all categories with subcategories. When I call <MAGE>/api/rest/eoarestapi/categories?type=rest the function _retrieveCollection() from the class Namespace_Restapi_Model_Api2_Category_Rest_Guest_V1 is being called. So far so good.
Now I am having the problem, that it returns the response in XML only and when I set the header explicitly to Accept: application/json, then I get the error 406 Not Acceptable An appropriate representation of the requested resource /api/rest/products could not be found on this server. Available variants: api.php , type application/x-httpd-php
This seems very strange to me as I can remember having worked with JSON response back in Magento 1.8.
As a fix I found this and that solution to retrieve JSON which works, but it doesn't seem to be a nice solution as it looks like it disables XML response completely.
Is there a better way to enable JSON output from the REST API in Magento 1.9?
Does anybody have some background knowledge on this?
First I defined #return mixed in my API interface
and than in your model I do this
$response = ['success' => 'ok', 'message' => 'json format'];
header('Content-Type: application/json');
echo json_encode($response); exit;
I achieved this by overriding my request model. My Steps are following:
1:Declare new module : Create app/etc/modules/Custom_RestJson.xml
<?xml version="1.0"?>
<config>
<modules>
<Custom_RestJson>
<active>true</active>
<codePool>local</codePool>
</Custom_RestJson>
</modules>
</config>
2. Create /app/code/local/Custom/RestJson/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Custom_RestJson>
<version>1.0.0</version>
</Custom_RestJson>
</modules>
<global>
<models>
<Custom_RestJson>
<class>Custom_RestJson_Model</class>
</Custom_RestJson>
<api2>
<rewrite>
<request>Core_Mage_Api2_Model_Request</request>
</rewrite>
</api2>
</models>
</global>
</config>
3. Create /app/code/local/Custom/RestJson/Model/Api2/Request.php
<?php
class Custom_RestJson_Model_Api2_Request extends Mage_Api2_Model_Request{
public function getAcceptTypes()
{
$qualityToTypes = array();
$orderedTypes = array();
foreach (preg_split('/,\s*/', $this->getHeader('Accept')) as $definition) {
$typeWithQ = explode(';', $definition);
$mimeType = trim(array_shift($typeWithQ));
// check MIME type validity
if (!preg_match('~^([0-9a-z*+\-]+)(?:/([0-9a-z*+\-\.]+))?$~i', $mimeType)) {
continue;
}
$quality = '1.0'; // default value for quality
if ($typeWithQ) {
$qAndValue = explode('=', $typeWithQ[0]);
if (2 == count($qAndValue)) {
$quality = $qAndValue[1];
}
}
$qualityToTypes[$quality][$mimeType] = true;
}
krsort($qualityToTypes);
foreach ($qualityToTypes as $typeList) {
$orderedTypes += $typeList;
}
return array_keys(array("application/json" => 1));
}
}

Punching a hole through Magento Full Page Cache correctly

I have been pulling my hair out over trying to get a hole punched out for the price block on the product page. I have looked at numerous sources, including some from you good people at stackoverflow, but I have been getting a fatal error, so something is incorrect. Here are some sources that I used:
http://invisiblezero.net/magento-ee-punch-hole-in-full-page-cache/
http://www.kingletas.com/2012/09/how-does-magento-full-page-cache-works.html
Magento full page cache
Trying get dynamic content hole-punched through Magento's Full Page Cache
How to implement magento cache hole punching for shopping cart block
As you can see, I have been all over, and I have read more in addition to this but some of them conflict a litt, and I think that is where I have my issue, now let me post some code for you.
cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<placeholders>
<SpecialPrice>
<block>catalog/product_price</block>
<name>product.pricing</name>
<placeholder>CATALOG_PRODUCT_PRICE</placeholder>
<container>MyStore_SpecialPrice_Model_Container_Cache</container>
<cache_lifetime>8640</cache_lifetime>
</SpecialPrice>
</placeholders>
</config>
cache.php
<?php
class MyStore_SpecialPrice_Model_Container_Cache extends Enterprise_PageCache_Model_Container_Abstract
{
/**
* Get customer identifier from cookies
*
* #return string
*/
protected function _getIdentifier()
{
return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
}
/**
* Get cache identifier
*
* #return string
*/
protected function _getCacheId()
{
return 'CATALOG_PRODUCT_PRICE' . md5($this->_placeholder->getAttribute('cache_id') . $this->_getIdentifier());
}
/**
* Render block content
*
* #return string
*/
protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');
$block = new $blockClass;
$block->setTemplate($template);
return $block->toHtml();
}
}
congig.xml
<?xml version="1.0"?>
<config>
<modules>
<MyStore_SpecialPrice>
<version>0.1.0</version>
</MyStore_SpecialPrice>
</modules>
<frontend>
<events>
<catalog_product_get_final_price>
<observers>
<MyStore_SpecialPrice_Model_Observer>
<class>MyStore_SpecialPrice_Model_Observer</class>
<method>setSpecialPrice</method>
</MyStore_SpecialPrice_Model_Observer>
</observers>
</catalog_product_get_final_price>
</events>
</frontend>
<admin>
<routers>
<SpecialPrice>
<use>admin</use>
<args>
<module>MyStore_SpecialPrice</module>
<frontName>SpecialPrice</frontName>
</args>
</SpecialPrice>
</routers>
</admin>
<global>
<models>
<SpecialPrice>
<class>MyStore_SpecialPrice_Model</class>
</SpecialPrice>
</models>
</global>
</config>
snippet from local.xml
<reference name="right">
<block type="catalog/product_price" name="product.pricing" template="catalog/product/product-price-block.phtml" before="-" >
Let me know if there is anything that jumps out to you.

Magento: Setting custom shipping method programmatically

I'm pretty new to Magento, and having problems trying to set a custom shipping method programmatically. I'm converting an xml from a thrid party into an order, and everything else (that I've worked on so far) is working fine. Also I'm having problems spelling "programmatically" but I won't ask for you help with that.
I set up my custom shipping method as follows:
To activate the shipping module in
app/etc/modules/Extension_Shipping.xml
<?xml version=
"1.0"?>
<config>
<modules>
<Extension_Shipping>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Shipping/>
</depends>
</Extension_Shipping>
</modules>
</config>
then to configure it in
app/code/local/Extension/Shipping/etc/config.xml
<?xml version=
"1.0" ?>
<config>
<modules>
<Extension_Shipping>
<version>0.1.0</version>
</Extension_Shipping>
</modules>
<global>
<models>
<extension_shipping>
<class>Extension_Shipping_Model</class>
</extension_shipping>
</models>
</global>
<default>
<carriers>
<extension_myrate>
<active>1</active>
<model>extension_shipping/carrier_myrate</model>
<title>Extension Shipping</title>
<name>Default Rate</name>
</extension_myrate>
</carriers>
</default>
</config>
then to add the class in
app/code/local/Extension/Shipping/Model/Carrier/MyRate.php
<?php
class Extension_Shipping_Model_Carrier_MyRate
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
{
protected $_code = 'extension_myrate';
protected $_isFixed = true;
public function collectRates(Mage_Shipping_Model_Rate_Request
$request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
$result = Mage::getModel('shipping/rate_result');
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier('extension_myrate');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('extension_myrate');
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice(5);
$method->setCost(2);
$result->append($method);
return $result;
}
public function getAllowedMethods()
{
return array('extension_myrate' => $this->getConfigData('name'));
}
}
Basically I followed http://www.magentotricks.com/creating-a-customer-magento-shipping-method/
I thought it all worked fine, as the shipping method now shows up in the checkout screen, and can be set both by customers or in the admin "create new order." However, I'm not able to set it programmatically.
In my controller I'm trying to set the shipping method using the code
$shippingAddress = $quote->getShippingAddress()->addData($addressData);
$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('extension_myrate')
->setPaymentMethod('checkmo');
To add to my confusion, it worked once. but only once out of quite a few test orders. changing the "setShippingMethod" to "freeshipping_freeshipping" or "flatrate_flatrate" makes it update the shipping to those correctly. because of that and because I'm new and still having problems with the file structure, I'm guessing my problem is with setShippingMethod('extension_myrate') but I'm not entirely sure. Any advice would be helpful and appreciated.

Categories