Stemming from my last question, I am stumped trying to do an override. I am doing exactly what MudithaE's answer here did, too.
I want to implement my own _prepareColumns() as found in the file app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php. I set up my module's directories and the files as below. While researching, I saw a lot of developers like to do Dev_Module_Block_Adminhtml_blah, so I tried changing the directory structure and class names everywhere in my code. No change. My Cycleworks_SalesGridImproved module appears in the System -> Config -> Advanced listing, too.
Files:
app/code/local/Cycleworks/SalesGridImproved/Adminhtml/Block/Sales/Order/Grid.php:
<?php
class Cycleworks_SalesGridImproved_Adminhtml_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid {
protected function _prepareColumns() // tried public too
{
parent::_prepareColumns();
...
...
$this->addColumn('created_at', array(
'header' => Mage::helper('sales')->__('Purchased On'),
'index' => 'created_at',
'type' => 'datetime',
'format' => 'MMM d, h:mm a',
'width' => '165px',
));
...
...
return $this;
}
}
app/code/local/Cycleworks/SalesGridImproved/etc/config.xml:
<?xml version="1.0"?>
<config>
<modules>
<!-- also tried: Cycleworks_SalesGridImproved -->
<Cycleworks_Adminhtml>
<version>0.0.01</version>
</Cycleworks_Adminhtml>
</modules>
<global>
<blocks>
<adminhtml>
<salesgridimproved>
<class>Cycleworks_SalesGridImproved_Adminhtml_Block_Sales_Order_Grid</class>
</salesgridimproved>
<rewrite>
<sales_order_grid>Cycleworks_SalesGridImproved_Adminhtml_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
</config>
And in /app/etc/modules/Cycleworks_SalesGridImproved.xml:
<?xml version="1.0"?>
<config>
<modules>
<Cycleworks_SalesGridImproved>
<active>true</active>
<codePool>local</codePool>
</Cycleworks_SalesGridImproved>
</modules>
</config>
Please show me see what I'm missing... Thanks!
Update:
Just found out the extension EM_DeleteOrder is also overriding the same sales order grid class that I am. His extension's configuration is more complicated than mine, as his is set up to be called before the Mage core. The config.xml sure is busy!
<?xml version="1.0"?>
<config>
<modules>
<EM_DeleteOrder>
<version>1.0.0</version>
</EM_DeleteOrder>
</modules>
<global>
<rewrite>
<em_emadmin_adminhtml_sales_order>
<from><![CDATA[#/admin/sales_order/#]]></from>
<to>/emadmin/adminhtml_sales_order/</to>
</em_emadmin_adminhtml_sales_order>
</rewrite>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>EM_DeleteOrder_Block_Adminhtml_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
<admin>
<routers>
<em_deleteorder>
<use>admin</use>
<args>
<module>EM_DeleteOrder</module>
<frontName>emadmin</frontName>
</args>
</em_deleteorder>
<adminhtml>
<args>
<modules>
<EM_DeleteOrder_Adminhtml before="Mage_Adminhtml">EM_DeleteOrder_Adminhtml</EM_DeleteOrder_Adminhtml>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
Do you have any thoughts how I can use similar syntax and get my module to work and not have to hack his code? Like with an after="Mage_Adminhtml"?
Final Update:
Sadly, the 3 answers below weren't the answer, it was the extension conflict. I'll answer my own question and mark it answered.
I just tried this and it works. I think by returning parent::_prepareColumns() that it's ignoring your change. Adding it at the top of the function then returning $this works fine for me.
<?php
class Cycleworks_SalesGridImproved_Adminhtml_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid {
protected function _prepareColumns() // tried public too
{
// ...
// ...
parent::_prepareColumns();
$this->addColumn('created_at', array(
'header' => Mage::helper('sales')->__('Purchased On'),
'index' => 'created_at',
'type' => 'datetime',
'format' => 'MMM d, h:mm a',
'width' => '165px',
));
// ...
// ...
return $this; #parent::_prepareColumns();
}
}
I'm answering myself, as this was a big lesson in extension conflicts and their resolution. Further, I learned a lot about our particular installation and how sloppy extensions can break everything.
As in the update, EM_DeleteOrder was overriding Adminhtml Block Sales Order Grid (absog). I also used the extension MDN_ExtensionConflict and while it wasn't detecting my exact conflict, it did show me that EM_DeleteOrder was using absog. I searched for extensions that would allow deletion of orders without using absog, which must be the easy way to go about it.
The extension Asperience_DeleteAllOrders manages to do this without overwriting the whole page and instead catches something in the router. Its config.xml is abstract art to me, so if you're an advanced developer, I think you'd appreciate his work more than I.
Ultimately, I found MageWorx_ExtendedOrders which replaces the entire absog with their own grid and has configurable additional columns. Included are custom shipping rates, order editing, deletion of orders, and order archiving. I am impressed with this extension for $149. I also am going through deleting the multiple extensions that were replaced with MageWorx_ExtendedOrders. I'm hacking their extension's code to put the columns in my desired order and to update the date format (and I'll share my changes with them as feature suggestions).
_prepareColumns() is protected, not public.
Try putting adminhtml folder inside block folder i.e. app/code/local/Cycleworks/SalesGridImproved/Block/Adminhtml/Sales/Order/Grid
Related
I have total 10 multi-store in a single domain, when customer ordering from different store invoice increment Id and Prefix is creating different. but I want only two different invoice type, prefix "1" for store id 6 and all other store prefix's should be same like '19' and all increment id should be same.
10 different store but invoice should be only two types.
Is there any good solution, highly appreciated.
thanks
You are require to follow below steps to do this:
1) - In the /Namespace/Module/etc/config.xml you have to write the following thing:
<config>
<modules>
<Namespace_Module>
<version>0.1.0</version>
</Namespace_Module>
</modules>
<global>
<models>
<eav>
<rewrite>
<entity_store>Namespace_Module_Model_Entity_Store</entity_store>
</rewrite>
</eav>
</models>
</global>
</config>
2) - Register module in magento module list under app/etc/modules/Namespace_Module.xml
<config>
<modules>
<Namespace_Module>
<active>true</active>
<codePool>local</codePool>
<depends />
</Namespace_Module>
</modules>
</config>
3) - You have to copy the same code under /Mage/Eav/Model/Entity/Store.php into your file under /Namespace/Module/Model/Entity/Store.php.
4) Edit your Store.php file: Please find below code
public function loadByEntityStore($entityTypeId, $storeId)
{
$this->_getResource()->loadByEntityStore($this, $entityTypeId, 1);//1 is your default store_id
return $this;
}
Replace it with below code
public function loadByEntityStore($entityTypeId, $storeId)
{
$this->_getResource()->loadByEntityStore($this, $entityTypeId, 1);//1 is your default store_id
return $this;
if($storeId==6){//6==StoreID
$this->_getResource()->loadByEntityStore($this, $entityTypeId, 1);//1 is your default store_id
}else{
$this->_getResource()->loadByEntityStore($this, $entityTypeId, 19);
}
}
Hope this will work for you. :)
Best of luck.
Below is the solution for all Store view. In this solution all store Ids will be same.
Find in app/code/mage/sales/model/entity/setup.php the following piece of code:
'invoice' => array(
'entity_model' => 'sales/order_invoice',
'table' =>'sales/order_entity',
'increment_model' =>'eav/entity_increment_numeric',
'increment_per_store'=>false,
and chance
'increment_per_store'=>false
To
'increment_per_store'=>true
I am trying to get to grips with calling and using models in magento.
My current task is to simply display a string held in a model by calling it from a controller.
When trying to call SimpleOutput.php I get an error message saying that a non object has been called. I have var_dumped it as you will see and it return false.
I have looked at my code and with my limited understanding of what I need to do in Magento I have everything correct. Obviously i'm missing something. Could someone please take a look and if it's a typo tell where to look and if it's more than a simple spelling mistake explain what ive missed and what I should have done and why?
My code is below
Ts/Firstmodule/etc/config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Ts_Firstmodule>
<version>0.1.0</version>
</Ts_Firstmodule>
</modules>
<models>
<firstmodule>
<class>Ts_Firstmodule_Model</class>
</firstmodule>
</models>
<frontend>
<routers>
<firstmodule>
<use>standard</use>
<args>
<module>Ts_Firstmodule</module>
<frontName>firstmodule</frontName>
</args>
</firstmodule>
</routers>
</frontend>
</config>
Ts/Firstmodule/controllers/indexController.php
class Ts_Firstmodule_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
$simple = Mage::getModel('ts_firstmodule/simpleoutput');
var_dump($simple);
}
}
Ts/Firstmodule/model/simpleoutput.php
class Ts_Firstmodule_Model_SimpleOutput extends Mage_Core_Model_Abstract
{
public function basicText()
{
echo 'this is some text from the simple output model inside the basic text function';
}
}
You must wrap <models> in <global>, just like this :
<global>
<models>
<firstmodule>
<class>Ts_Firstmodule_Model</class>
</firstmodule>
</models>
</global>
Don't hesitate to take a look at the source of the simpler core modules (eg, GoogleAnalytics), to see how they're done and understand the logic behind it.
Like always :
Mage::getModel('ts_firstmodule/simpleoutput');
When you do a getModel / getBlock / helper / etc
The first part of the parameter string is the XML node of the layer definied in the config.xml
The second part is the full path to your file from the layer folder container.
So, in your case : Mage::getModel('firstmodule/simpleoutput'); should load Ts/Firstmodule/Model/Simpleoutput.php
Note : be carefull of the case of your resources (take a look a standard magento for good practices) !
You should modify the config.xml file and add a <global> tag around your <models> tag:
<global>
<models>
<firstmodule>
<class>Ts_Firstmodule_Model</class>
</firstmodule>
</models>
<global>
After this, in order to instantiate a model use it like this:
Mage::getModel('firstmodule/simpleoutput')
The first part of the getModel method (up until /) should be the tag name you set in config.xml right under <models> tag. In your case firstmodule.
I'm trying to add an 'a href' / link in an Attribute Field for a product.
However, the methods that I'm using are not working - although they work in CMS page content. When I view the product, the attribute with the link is displayed, but the actual URL does not seem to be generated correctly (404 error)
I've tried the following:
1. Test link 1
2. Test link 2
3. Test link 3
What am I doing wrong?
Your help is appreciated in advance
Thank you!
Magento EAV attributes values will not be parsed by PHP on their own. For display to the user, they are rendered through a frontend model. See eav_attribute table for examples.
Based on the "we do not want to display the entire url, just a text link" comment, you need an attribute with a custom frontend model. I'm guessing that it was added via the Admin Panel, which won't allow to add custom frontend models. Whereas adding the frontend model requires a script, I'd recommend adding the attribute via script in the first place.
To install this attribute properly , Magento needs to execute a setup script, which is a Magento term for (usually) PHP code which is executed exactly once with the ability to manipulate the database. Running these presupposes a module exists:
app/etc/modules/Your_Module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Your_Module>
<active>true</active>
<codePool>local</codePool>
</Your_Module>
</modules>
</config>
app/code/local/Your/Module/etc/config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Your_Module>
<version>1.0.0.0</version>
</Your_Module>
</modules>
<global>
<models>
<your_module>
<class>Your_Module_Model</class>
</your_module>
</models>
<resources>
<your_module_setup>
<setup>
<module>Your_Module</module>
</setup>
</your_module_setup>
</resources>
</global>
</config>
app/code/local/Your/Module/sql/your_module_setup/install-1.0.0.0.php:
<?php
$installer = Mage::getResourceModel('catalog/setup','catalog_setup');
/* #var $installer Mage_Catalog_Model_Resource_Setup */
$installer->startSteup();
$installer->addAttribute(
'catalog_product',
'unique_attr_code',
array(
'label' => 'Link to Product',
'required' => 'false', //or true if appropriate
'group' => 'General', //Adds to all sets
'frontend' => 'your_module/frontend_url'
)
);
$installer->endSetup();
app/code/local/Your/Module/Model/Frontend/Url.php:
class Your_Module_Model_Frontend_Url
extends Mage_Eav_Model_Entity_Attribute_Frontend_Abstract
{
public function getUrl($object)
{
$url = false;
if ($path = $object->getData($this->getAttribute()->getAttributeCode())) {
$url = Mage::getUrl('path');
}
return $url;
}
}
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.
I try to rewrite core file from magento.
Somehow it does not overwrite the code. I try to overwrite the function getProduct().
Tipfix/Block/Product/View.php
<?php
class WP_Tipfix_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View
{
public function getProduct()
{
if (!Mage::registry('product') && $this->getProductId()) {
$product = Mage::getModel('catalog/product')->load($this->getProductId());
Mage::register('product', $product);
}
//return Mage::registry('product');
}
}
Tipfix/etc/config.xml
<blocks>
<WP_Tipfix>
<class>WP_Tipfix_Block</class>
</WP_Tipfix>
<catalog>
<rewrite>
<product_view>WP_Tipfix_Block_Catalog_Product_View</product_view>
</rewrite>
</catalog>
</blocks>
I have know idea what i'm doing wrong.
Gr.
Lex
Your class is WP_Tipfix_Block_Catalog_Product_View which means it must be in the folder WP/Tipfix/Block/Catalog/Product/View.php. You must either move your Product directory into a new directory called Catalog in that place or rename your class (both the class and in the XML) to WP_Tipfix_Block_Product_View. I recommend moving the file.
Please change the config.xml content of your module to this, and I'm sure that it should work:-
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<WP_Tipfix>
<version>1.0.0</version>
</WP_Tipfix>
</modules>
<global>
<blocks>
<wptipfix>
<class>WP_Tipfix_Block</class>
</wptipfix>
<catalog>
<rewrite>
<product_view>WP_Tipfix_Block_Catalog_Product_View</product_view>
</rewrite>
</catalog>
</blocks>
</global>
</config>
Hope it helps.
UPDATE:-
After Ben's comment, I feel that I should have mentioned that the OP must also use the solution as mentioned by Max in his answer. So the OP will need a combined effort to fix his problem.