Magento 2 - Controller returning blank page - php

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.

Related

Manipulate Magento\SalesRule\Model\ResourceModel\Rule\Collection::mapAssociatedEntities with Plugins

I have been trying to filter the coupon coupons for hours now.
I tried to manipulate the function mapAssociatedEntities in the file /vendor/magento/module-sales-rule/Model/ResourceModel/Rule/Collection.php with a plugin, but I can't get it to work and now I'm hoping for your help.
/etc/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<type name="Magento\SalesRule\Model\ResourceModel\Rule\Collection">
<plugin name="coupon_restricted_plugin" type="Vendor\Modul\Plugin\CouponCollectionPlugin" sortOrder="1"/>
</type>
</config>
/app/code/Vendor/Modul/Plugin/CouponCollectionPlugin.php
<?php
namespace Vendor\Modul\Plugin;
class CouponCollectionPlugin
{
public function aroundMapAssociatedEntities(
\Magento\SalesRule\Model\ResourceModel\Rule\Collection $subject,
\Closure $proceed,
$entityType,
$objectField
){
var_dump('Here: ' . __METHOD__.__FUNCTION__'<br>');
$result = $proceed($entityType, $objectField);
return $result;
}
}
I also like to take another way to override the mapAssociatedEntities function.
I need to narrow down the coupon codes to the user
Edit// Magento 2.4.5-p1

Magento 2 : Add custom script just after head tag

i want to add custom script just after the start of head tag.
like.
<head>
<script>console.log("I'm loaded!");</script>
i tried to add code in default_head_blocks.xml
<referenceContainer name="head.additional">
<block class="Custom\Module\Block\Success" template="Custom_Module::success/head.phtml"/>
</referenceContainer>
=> output :
<script>console.log("I'm loaded!");</script>
</head>
this code are using add script before the end of head tag.
Please check Below code
Block => Custom/Module/Block/Onepage/Success.php
namespace Custom\Module\Block\Onepage;
use Magento\Framework\View\Element\Template;
class Success extends \Magento\Checkout\Block\Onepage\Success {
public function getOrder()
{
$objectManager =\Magento\Framework\App\ObjectManager::getInstance();
$helper = $objectManager->get('Custom\Module\Helper\Data');
$lastOrderId = $this->getOrderId();
if (empty($lastOrderId))
{
return null;
}
$orderData = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($this->getOrderId());
return $orderData;
}
}
Helper => Custom\Module\Helper\Data.php
namespace Custom\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* #param \Magento\Framework\App\Helper\Context $context
*/
protected $_request;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\Request\Http $request
) {
$this->_request = $request;
parent::__construct($context);
}
public function getConfigValue($value = '') {
return $this->scopeConfig
->getValue($value,\Magento\Store\Model\ScopeInterface::SCOPE_STORE);
}
public function getTemplate()
{
if ($this->getConfigValue('custom_general/general/active') == 1) {
$template = 'Custom_Module::checkout/success.phtml';
} else {
$template = 'Magento_Checkout::success.phtml';
}
return $template;
}
}
di.xml => etc\di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/framework/ObjectManager/etc/config.xsd">
<preference for="Magento\Checkout\Block\Onepage\Success" type="Custom\Module\Block\Onepage\Success"/>
</config>
Layout Xml => Custom/Module/view/frontend/layout/default.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="require.js">
<action method="setTemplate">
<argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
</action>
</referenceBlock>
</body>
</page>
Template => Custom/Module/view/frontend/templates/success/head.phtml
<script>
console.log("I'm loaded!");
</script>
Please help me and solve this issue
Thanks in advance.
I am not sure if this is the correct way or not, but I have got a lead.
By default magento 2 usees the root.phtml file to setup head content accordingly, which is located in vendor/magento/module-theme/view/base/templates/root.phtml (if it has not been overridden).
Here, the $requireJs variable is loaded first in the head block. The $requireJs variable is defined in the render method inside Page class -which is located in vendor/magento/framework/view/Result/Page.php.
In this file, $requireJs contains the require.js block. And the require.js block is defined in vendor/Magento/module-theme/view/frontend/layout/default.xml :
<block name="require.js" class="Magento\Framework\View\Element\Template" template="Magento_Theme::page/js/require_js.phtml" />
Solution
1) Copy require_js.phtml from vendor/magento/module-theme/view/frontend/templates/page/js to your theme app/design/frontend/{VENDOR}/{THEME_NAME}/Magento_Theme/templates/page/js/
2) Now you can add your script like this:
<script>
console.log("I'm loaded!");
var require = {
"baseUrl": "<?php /* #escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
};
</script>
UPDATE (Using Module)
Overriding the require.js block is not an elegant solution. if anyone has a good solution please answer. For now edit your layout xml:
<referenceBlock name="require.js">
<action method="setTemplate">
<argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
</action>
</referenceBlock>
and inside success/head.phtml add your code:
<script>
console.log("I'm loaded!");
var require = {
"baseUrl": "<?php /* #escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
};
</script>
I found a simple way of doing it that seems very reasonable, because it uses existing features in the adminhtml theme without any need to override/intercept anything.
Background
Like #sanchit-gupta mentioned, the root.phtml template is used as the basis to render both the frontend and adminhtml areas, and so is the associated class \Magento\Framework\View\Result\Page, which always looks for a block named head.additional before rendering.
This block exists in the frontend layouts by default, but unfortunately it doesn't exist in the adminhtml layout.
Solution
With that in mind, the current best way (as of 2.3.x) to add inline <scripts> to the adminhtml's <head> section is to add any head.additional block: it will be automatically rendered by the framework. It either has to be a ListText block so that it renders all it's children automatically, or a Template with a specified template file. I actually chose too nest my actual block inside the ListText block just to keep the same mechanism available as in the frontend area (i.e. for compatibility with other plugins that might be doing the same).
Example
In your custom module or theme, add a layout update that inserts the following block into the body of the page layout (which is just to do it the same way as it's done in Magento 2 core for the frontend area):
<body>
<block class="Magento\Framework\View\Element\Text\ListText" name="head.additional">
<block name="your_block" class="Magento\Framework\View\Element\Template" template="Your_Module::your/template.phtml" />
</block>
</body>
Done! Your template will render inside <head></head> – without any awkward overrides or "hacks".
What's more, if other modules also reference head.additional in the adminhtml area, they will be compatible with your code.

Joomla Component: View: Get values from field

I'm new to Joomla, especially to component development. Anyway, here's my question:
site\views\plaingallery\tmpl\default.xml
<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_PLAINGALLERY_PLAINGALLERY_VIEW_DEFAULT_TITLE">
<message>
<![CDATA[COM_PLAINGALLERY_PLAINGALLERY_VIEW_DEFAULT_DESC]]>
</message>
</layout>
<fields name="request"
addfieldpath="/administrator/components/com_plaingallery/models/fields">
<fieldset name="request">
<field name="galleryFolder" type="folderlist" default="" recursive="true"
label="Select a folder" directory="images" filter="" exclude="" width="300"
hide_none="true" hide_default="true" stripext="" />
</fieldset>
</fields>
</metadata>
site\views\plaingallery\view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HTML View class for the PlainGallery Component
*/
class PlainGalleryViewPlainGallery extends JViewLegacy
{
// Overwriting JView display method
function display($tpl = null)
{
// Assign data to the view
$this->msg = 'I am new to Joomla';
// Display the view
parent::display($tpl);
}
}
My question is: How do I access the value from the field[name="galleryFolder"] the user provided in the menu configuration?
Thanks for your help! I really do appreciate it.
This parameter is located in the query variable of the menu item.
You can try this for example:
$app = JFactory::getApplication();
/* Default Page fallback*/
$active = $app->getMenu()->getActive();
if (NULL == $active) {
$active = $app->getMenu()->getDefault();
}
if ( isset($active->query['galleryFolder']) ) {
$galleryFolder = $active->query['galleryFolder'];
}

Custom url in Magento

I want to create url like {base_url}/customize/{product_slug}.phtml
Could please help how to make this of url Magento?
Currently I have created "CustomizeController.php" file
<?php
class ProductCustomizer_ProductCustomizer_CustomizeController extends Mage_Core_Controller_Front_Action {
public function indexAction(){
echo 'test mamethode';
$product = Mage::getModel("productcustomizer/customizeproduct")->getProduct();
}
public function mamethodeAction(){
echo 'test mamethode';
}
}
and below code in config.xml file
<productcustomizer_customize_index>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
<reference name="content">
<block type="productcustomizer/customize" name="productcustomizer_customize" template="productcustomizer/customize.phtml"/>
</reference>
</productcustomizer_customize_index>
Please assign in $url_key to resolve the issue.
$rewrite = Mage::getModel('core/url_rewrite');
$rewrite->setStoreId($store_id) ->setIdPath('customize/'.$url_key) ->setRequestPath('customize/'.$url_key.'.html') ->setTargetPath('customize/index/action/id/'.$url_key) ->setIsSystem(true) ->save();
I have found solution you can set routing using config.xml file
<global>
<rewrite>
<productcustomizer_url>
<from><![CDATA[#^/customize/#]]></from>
<to><![CDATA[/productcustomizer/customize/index/product/]]></to>
<complete>1</complete>
</productcustomizer_url>
</rewrite>
<global>

Magento REST API Create Method - Resource Method Not Implemented

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.

Categories