ok, so this isn't my first mass action but, this does have me scratching my head.
I made a module CLR_exportMassAction. Deployed it on the good old localhost with no problems. However when I move the files out to my server, nothing happens. I have reindexed and flushed caches. I have a feeling its some configuration weirdness and magento isn't hooking in my module.
Here is my code:
\local\CLR\exportMassAction\etc\config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<global>
<models>
<CLR_exportMassAction>
<class>CLR_exportMassAction_Model</class>
</CLR_exportMassAction>
</models>
</global>
<adminhtml>
<events>
<adminhtml_block_html_before>
<observers>
<CLR_exportMassAction>
<type>singleton</type>
<class>CLR_exportMassAction/observer</class>
<method>addExportMassactionToProductGrid</method>
</CLR_exportMassAction>
</observers>
</adminhtml_block_html_before>
</events>
</adminhtml>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<CLR_exportMassAction before="Mage_Adminhtml">CLR_exportMassAction_Adminhtml</CLR_exportMassAction>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
local\CLR\exportMassAction\Model\Observer.php
<?php
class CLR_exportMassAction_Model_Observer
{
public function addExportMassactionToProductGrid($observer)
{
$block = $observer->getBlock();
if($block instanceof Mage_adminHtml_Block_Catalog_Product_Grid) {
$block ->getMassactionBlock()->addItem('export', array(
'label' => Mage::helper('catalog')->__('Export to CSV'),
'url' => $block->getUrl('*/*/massExport', array('_current'=>true)),
));
}
}
}
local\CLR\exportMassAction\controllers\Adminhtml\Catalog\ProductController.php
<?php
class CLR_exportMassAction_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller_Action
{
public function massExportAction()
{
$productIds = $this->getRequest()->getParam('product');
if (!is_array($productIds)) {
$this->_getSession()->addError($this->__('Please select product(s).'));
$this->_redirect('*/*/index');
}
else {
//write headers to the csv file
$content = "id,name,url,sku\n";
try {
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
$content .= "\"{$product->getId()}\",\"{$product->getName()}\",\"{$product->getProductUrl()}\",\"{$product->getSku()}\"\n";
}
} catch (Exception $e) {
$this->_getSession()->addError($e->getMessage());
$this->_redirect('*/*/index');
}
$this->_prepareDownloadResponse('export.csv', $content, 'text/csv');
}
}
}
app\etc\CLR_exportMassAction.xml
<config>
<modules>
<CLR_exportMassAction>
<active>true</active>
<codePool>community</codePool>
</CLR_exportMassAction>
</modules>
</config>
I am just looking for a pointer really on where to go from here; I am not sure what the next troubleshooting options are.
Most likely, your local setup is running on a case-insensitive file system (are you on Windows?), whereas your server is running on a case-sensitive file system (probably Linux).
Magento does a lot of string manipulation to convert class names into file names and such. For example, see Varien_Autoload::autoload(), which I presume is causing your problem:
$classFile = str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $class)));
If you plug in your observer class (CLR_exportMassAction_Model_Observer, after resolving CLR_exportMassAction/observer), you get:
str_replace('_', ' ', 'CLR_exportMassAction_Model_Observer')
= 'CLR exportMassAction Model Observer'
ucwords('CLR exportMassAction Model Observer')
= 'CLR ExportMassAction Model Observer'
str_replace(' ', DIRECTORY_SEPARATOR, 'CLR ExportMassAction Model Observer')
= 'CLR/ExportMassAction/Model/Observer'
So, Magento is looking for a file called CLR/ExportMassAction/Model/Observer.php, but your file is called CLR/exportMassAction/Model/Observer.php - see the lower-case e?
There might be some other casing issues as well, but this is the most prominent one.
I recommend renaming your module namespace from CLR to Clr, and your actual module from exportMassAction to Exportmassaction, and making sure that all of your class names and file names match precisely. This is the easiest way to avoid casing issues with Magento (even if you have multiple words in the same identifier).
Related
I've got a Magento store (1.9) with a very simple plugin. It changes the customer group when someone places an order in a website. But we also work with a POS.
In the POS the plugin is also trying to change the customer group but it gives an error.
So what I want to do is disable the plugin for our local IP (or User).
The code is the following or check Github:
observer.php
<?php
class RvdH_GroupChange_Model_Observer
{
public function changeGroup(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
$customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
/*$event = $observer->getEvent(); //Fetches the current event"
$customer = $event->getCustomer();
$dbcustomer = Mage::getModel('customer/customer')->load($customer[entity_id]);*/
// ensure it's not guest checkout
if ($customer->getId()) {
$customer->setGroupId(5);
$customer->save();
}
}
}
config.xml
<?xml version="1.0"?>
<config>
<modules>
<RvdH_GroupChange>
<version>0.1.0</version>
</RvdH_GroupChange>
</modules>
<global>
<models>
<RvdH_GroupChange>
<class>RvdH_GroupChange_Model</class>
<resourceModel>module_mysql4</resourceModel>
</RvdH_GroupChange>
</models>
<events>
<sales_order_place_after>
<observers>
<RvdH_GroupChange>
<class>RvdH_GroupChange_Model_Observer</class>
<method>changeGroup</method>
</RvdH_GroupChange>
</observers>
</sales_order_place_after>
</events>
</global>
</config>
Solved.
I just had to change the <global> tag to <frontend> in the config.xml.
Now it only works in frontend and not global.
Attempting to override the Cms/controllers/IndexController.
This is the directory structure of my module -
Local/MyCompany/FourOhFourExp/controllers/IndexController.php
Local/MyCompany/FourOhFourExp/etc/config.xml
The code for my IndexController is
<?php
require_once 'Mage'. DS .'Cms'. DS .'controllers'. DS .'IndexController.php';
class MyCompany_FourOhFourExp_IndexController extends Mage_Cms_IndexController
{
public function noRouteAction($coreRoute = null){
Mage::log('First Function');
header("Location: new_route.html");
die();
}
public function defaultNoRouteAction()
{
Mage::log('Second function!');
header("Location: new_route.html");
die();
}
}
?>
and this is the code for my config.xml file
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<MyCompany_FourOhFourExp>
<version>0.1.0</version>
</MyCompany_FourOhFourExp>
</modules>
<frontend>
<routers>
<cms>
<args>
<modules>
<MyCompany_FourOhFourExp before="Mage_Cms">MyCompany_FourOhFourExp</MyCompany_FourOhFourExp>
</modules>
</args>
</cms>
</routers>
<events>
<controller_action_noroute>
<observers>
<cms>
<class>cms/observer</class>
<method>noRoute</method>
</cms>
</observers>
</controller_action_noroute>
</frontend>
</config>
Hoping someone can explain why this isn't overriding. I've looked through numerous tutorials and blog posts but have yet to figure out why it doesn't work.
There are lot of issue:
1)Modulepath:
As your controller class is MyCompany_FourOhFourExp_IndexController then path of class should be
app/code/local/MyCompany/FourOhFourExp
Local/MyCompany/controllers/IndexController
Local/MyCompany/etc/config.xml
change to
Local/MyCompany/FourOhFourExp/controllers/IndexController/php
Local/MyCompany/FourOhFourExp/etc/config.xml
2)Mage cms controller donot add properly
require_on Mage::getModuleDir('controllers', 'Mage_Cms'). DS .'IndexController.php';
What need to do:
add to app/code/local/Mage/Cms/controllers/IndexController.php , Mage::dispatchEvent('cms_controller_action_noroute', array('action'=>$this));
in your custom module, catch the Event
I am using an extension, Blue Jalappeno Order Export for exporting orders, which works great. I modified one of the output format options to work for our fulfillment company and it is working well for us.
Now we need another export that uses a different format. I have the format fairly nailed down.
My problem is with calling the new massAction in the order grid.
This works to show the new action #2 in the pull down.
class Webshopapps_Ordermanager_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid
{
protected function _prepareMassaction()
{
parent::_prepareMassaction();
if (Mage::getStoreConfig("order_export/export_orders/active")) {
$this->getMassactionBlock()->addItem('ordermanager', array(
'label'=> Mage::helper('sales')->__('Export orders IFS'),
'url' => $this->getUrl('*/sales_order_export/csvexport'),
));
}
if (Mage::getStoreConfig("order_export/export_orders2/active")) {
$this->getMassactionBlock()->addItem('ordermanager2', array(
'label'=> Mage::helper('sales')->__('Export orders QB'),
'url' => $this->getUrl('*/sales_order_export/qbexport'),
));
}
}
}
The first, working export still works. The second does show up and allows me to select and submit it but behaves differently. The url for the first never changed (/admin/sales_order/index) but the download box pops up. The url for the second changes to admin/sales_order_export/qbexport/ and presents a white screen
What I'd like it to do is call a different method in the same controller. Or pass a parameter to one method.
What I'm trying:
I added a method in the same controller used for the first addItem.
class Webshopapps_Ordermanager_Sales_Order_ExportController extends Mage_Adminhtml_Controller_Action
{
public function csvexportAction() // First working mass action
{
$orders = $this->getRequest()->getPost('order_ids', array());
switch(Mage::getStoreConfig('order_export/export_orders/output_type')){
case 'Multi':
$file = Mage::getModel('webshopapps_ordermanager/export_multi')->exportOrders($orders);
$this->_prepareDownloadResponse($file, file_get_contents(Mage::getBaseDir('export').'/'.$file));
break;
case 'Standard':
$file = Mage::getModel('webshopapps_ordermanager/export_csv')->exportOrders($orders);
$this->_prepareDownloadResponse($file, file_get_contents(Mage::getBaseDir('export').'/'.$file));
break;
}
}
public function qbexportAction()
{
$orders = $this->getRequest()->getPost('order_ids', array());
switch(Mage::getStoreConfig('order_export/export_orders/output_type2')){
case 'Qb':
$file = Mage::getModel('webshopapps_ordermanager/export_qb')->exportOrders($orders);
$this->_prepareDownloadResponse($file, file_get_contents(Mage::getBaseDir('export').'/'.$file));
break;
case 'Standard':
$file = Mage::getModel('webshopapps_ordermanager/export_csv')->exportOrders($orders);
$this->_prepareDownloadResponse($file, file_get_contents(Mage::getBaseDir('export').'/'.$file));
break;
case 'Mscrm':
$file = Mage::getModel('webshopapps_ordermanager/export_mscrm')->exportOrders($orders);
$this->_prepareDownloadResponse($file, file_get_contents(Mage::getBaseDir('export').'/'.$file));
break;
}
}
And the config.xml. I have looked and do not understand what makes the first massaction call the correct controller and action, but not the second. A glitch in my understanding that I need corrected.
<config>
<modules>
<Webshopapps_Ordermanager>
<version>0.0.1</version>
</Webshopapps_Ordermanager>
</modules>
<global>
<models>
<webshopapps_ordermanager>
<class>Webshopapps_Ordermanager_Model</class>
</webshopapps_ordermanager>
</models>
<helpers>
<webshopapps_ordermanager>
<class>Webshopapps_Ordermanager_Helper</class>
</webshopapps_ordermanager>
</helpers>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>Webshopapps_Ordermanager_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<Webshopapps_Ordermanager before="Mage_Adminhtml">Webshopapps_Ordermanager</Webshopapps_Ordermanager>
</modules>
</args>
</adminhtml>
</routers>
</admin>
<adminhtml>
<translate>
<modules>
<Webshopapps_Ordermanager>
<files>
<default>Webshopapps_Ordermanager.csv</default>
</files>
</Webshopapps_Ordermanager>
</modules>
</translate>
<default>
<ordermanager>
<condition_name>order_export</condition_name>
</ordermanager>
</default>
<acl>
<resources>
<admin>
<children>
<system>
<children>
<config>
<children>
<order_export>
<title>Export Orders</title>
</order_export>
</children>
</config>
</children>
</system>
</children>
</admin>
</resources>
</acl>
</adminhtml>
</config>
My problem is when the data profil runs, its like it isn't picking up covert_adapter_category at all.... I can't seem to eye whats missing... any ideas?
Output from dataflow import:
Starting profile execution, please wait...
Warning: Please do not close the window during importing/exporting data
Starting Mage_Dataflow_Model_Convert_Adapter_Io :: load
Loaded successfully: "/opt/bitnami/apps/magento/htdocs/var/import/Categories.csv".
Starting Mage_Dataflow_Model_Convert_Parser_Csv :: parse
Method "parse" not defined in adapter catalog/convert_adapter_category.
Finished profile execution.
config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Import_Catalog>
<version>0.1.0</version>
</Import_Catalog>
</modules>
<global>
<models>
<catalog>
<rewrite>
<convert_adapter_category>Import_Catalog_Model_Convert_Adapter_Category</convert_adapter_category>
</rewrite>
</catalog>
</models>
</global>
</config>
protected $_stores;
/**
* Category display modes
*/
protected $_displayModes = array( 'PRODUCTS', 'PAGE', 'PRODUCTS_AND_PAGE');
public function parse()
{
$batchModel = Mage::getSingleton('dataflow/batch');
/* #var $batchModel Mage_Dataflow_Model_Batch */
$batchImportModel = $batchModel->getBatchImportModel();
$importIds = $batchImportModel->getIdCollection();
foreach ($importIds as $importId) {
//print '<pre>'.memory_get_usage().'</pre>';
$batchImportModel->load($importId);
$importData = $batchImportModel->getBatchData();
$this->saveRow($importData);
}
}
Your current config.xml is set up to rewrite Magento's definition of Mage_Catalog_Model_Convert_Adapter_Category with your implementation, Import_Catalog_Model_Convert_Adapter_Category. Unfortunately the Mage_Catalog_Model_Convert_Adapter_Category doesn't actually exist in Magento, as far as I can see.
I suggest you change your config.xml to define your own class prefixes for your models, like the following:
<config>
...
<global>
<models>
<customimport>
<class>Import_Catalog_Model</class>
</customimport>
</models>
</global>
...
</config>
Then edit your Dataflow profile to use the adapter called customimport/convert_adapter_category, after you've implemented the logic.
Don't panic just flush the cache and run the profile again. This should fix the issue.
I've made a simple module that adds extra fields to the Sales > Order Grid. It works great but the problem is that another module we're using <rewrites> the order grid to add their field to the grid. I wanted to try to change it to use Events instead (besides, it's a better method)...
The issue is that I've been trying and trying and I just can't make it happen. (Maybe I just can't grasp the event/observer concept yet...)
Here is my current module structure:
app/code/local/Artizara/OrderGridAdditions/
app/code/local/Artizara/OrderGridAdditions/Block/Sales/Order/Grid.php
app/code/local/Artizara/OrderGridAdditions/etc/config.xml
app/code/local/Artizara/OrderGridAdditions/controllers [empty]
app/code/local/Artizara/OrderGridAdditions/Helper [empty]
app/code/local/Artizara/OrderGridAdditions/Model [empty]
Inside my Grid.php file, I have copied the main Grid.php file contents into my Grid.php file and edited the _getCollectionClass(), _prepareCollection() and _prepareColumns() functions.
I've changed the _getCollectionClass() to this:
//return 'sales/order_grid_collection';
return 'sales/order_collection';
I've changed the _prepareCollection() to this:
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->getSelect()->joinLeft(array('sfog' => 'sales_flat_order_grid'),'main_table.entity_id = sfog.entity_id',array('sfog.shipping_name','sfog.billing_name'));
$collection->getSelect()->joinLeft(array('sfo'=>'sales_flat_order'),'sfo.entity_id=main_table.entity_id',array('sfo.customer_email','sfo.weight','sfo.discount_description','sfo.increment_id','sfo.store_id','sfo.created_at','sfo.status','sfo.base_grand_total','sfo.grand_total','shipping_description','sfo.total_item_count'));
$collection->getSelect()->joinLeft(array('sfoa'=>'sales_flat_order_address'),'main_table.entity_id = sfoa.parent_id AND sfoa.address_type="shipping"',array('sfoa.street','sfoa.city','sfoa.region','sfoa.postcode','sfoa.telephone'));
//$collection->getSelect()->joinLeft(array('sfop' => 'sales_flat_order_payment'),'main_table.entity_id = sfop.entity_id',array('sfop.method'));
$this->setCollection($collection);
return parent::_prepareCollection();
I've added columns to the _prepareColumns() like this (only added one here as example):
$this->addColumn('total_item_count', array(
'header' => Mage::helper('sales')->__('Total Items'),
'index' => 'total_item_count',
'filter_index' => 'sfo.total_item_count',
'width' => '50px',
));
In my config.xml file I have a simple <rewrite>:
<modules>
<Artizara_OrderGridAdditions>
<version>0.1.0</version>
</Artizara_OrderGridAdditions>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>Artizara_OrderGridAdditions_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
<ordergridadditions>
<class>Artizara_OrderGridAdditions_Block</class>
</ordergridadditions>
</blocks>
</global>
Changing it over to Events/Observers
I've been trying a lot to change this up to a module that uses an Event but am hitting a wall with it. I've been trying to follow some other answers on here (the ones that are not rewrites, but they use a different method to add custom tables to the grid from the database). I'm looking to use the same setup I already have.
I've added /Helper/Data.php container that contains this:
class Artizara_OrderGridAdditions_Helper_Data extends Mage_Core_Helper_Abstract{ }
In /etc/config.xml I've tried many things. Here's my latest attempt:
<modules>
<Artizara_OrderGridAdditions>
<version>0.1.0</version>
</Artizara_OrderGridAdditions>
</modules>
<adminhtml>
<events>
<adminhtml_block_html_before>
<observers>
<Artizara_OrderGridAdditions_Observer>
<class>Artizara_OrderGridAdditions_Model_Observer</class>
<method>addAdditionsToGrid</method>
</Artizara_OrderGridAdditions_Observer>
</observers>
</adminhtml_block_html_before>
</events>
</adminhtml>
<global>
<models>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Model</class>
</Artizara_OrderGridAdditions>
</models>
<blocks>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Block</class>
</Artizara_OrderGridAdditions>
</blocks>
<helper>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Helper</class>
</Artizara_OrderGridAdditions>
</helper>
</global>
Then in /Model/Observer.php I have:
class Artizara_OrderGridAdditions_Model_Observer {
public function addAdditionsToGrid(Varien_Event_Observer $observer) {
// code here
}
}
Inside addAdditionsToGrid(), I've tried many different things including copying the entire Grid.php file but nothing seems to work (errors) :(
Please help guide me in remaking this simple module using Events please!
There is no (good) way to add a column to Sales Order Grid with Observers, because there is no event call. Take a look yourself for Mage::dispatchEvent inside Mage_Adminhtml_Block_Sales_Order_Grid and all superclasses.
I think the best practice is extend the grid class like this:
class Artizara_OrderGridAdditions_Block_Sales_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid {
protected function _prepareColumns() {
$this->addColumn(/* your definition here */);
}
}
If you really need do this by observers, you can watch the adminhtml_block_html_before event and dig a way out, but a lot of blocks will call this event either.