Title says it, I created a small reports module to just display some very basic things, but my admin view is NOT displaying. I end up receiving a 404 not found with the URL of /index.php/modulename/adminhtml_modulename/index/key/{the key}/
Here's the tree of my module:
app
├── code
│ └── local
│ └── Company
│ └── ModuleName
│ ├── Block
│ │ ├── ModuleName.php
│ │ └── adminhtml
│ │ ├── ModuleName
│ │ │ └── Grid.php
│ │ └── ModuleName.php
│ ├── Helper
│ │ └── Data.php
│ ├── Model
│ │ └── ModuleName.php
│ ├── controllers
│ │ └── Adminhtml
│ │ └── ModuleNameController.php
│ └── etc
│ └── config.xml
├── design
│ └── adminhtml
│ └── default
│ └── default
│ └── layout
│ └── modulename.xml
└── etc
└── modules
└── Company_ModuleName.xml
And here are the file(s):
app/code/local/Company/ModuleName/Block/Adminhtml/ModuleName/Grid.php
<?php
Class Company_ModuleName_Block_Adminhtml_ModuleName_Grid Extends Mage_Adminhtml_Block_Report_Grid
{
public function __construct()
{
parent::__construct();
$this->setId('modulenameGrid');
$this->setDefaultSort('created_at');
$this->setDefaultDir('ASC');
$this->setSaveParametersInSession(true);
$this->setSubReportSize(false);
}
protected function _prepareCollection()
{
parent::_prepareCollection();
$this->getCollection()->initReport('modulename/modulename'); //indicator for model used to get data.
return $this;
}
protected function _prepareColumns()
{
$this->addColumn('ordered_qty', array(
'header' =>Mage::helper('reports')->__('Quantity Ordered'),
'align' =>'right',
'index' =>'ordered_qty',
'type' =>'number'
'total' =>'sum', //indicator that this field must be totalized at the end.
));
$this->addColumn('item_id', array(
'header' => Mage::helper('modulename')->__('Item ID'),
'align' => 'right',
'index' => 'item_id',
'type' => 'number',
'total' => 'sum',
));
$this->addExportType('*/*/exportCsv', Mage::helper('modulename')->__('CSV'));
$this->addExportType('*/*/exportXml', Mage::helper('modulename')->__('XML'));
return parent::_prepareColumns();
}
public function getRowUrl($row)
{
return false;
}
public function getReport($from, $to)
{
if (empty($from)) $from = $this->getFilter('report_from');
if (empty($to)) $to = $this->getFilter('report_to');
$totalObj = Mage::getModel('reports/totals');
$totals = $totalObj->countTotals($this, $from, $to);
$this->setTotals($totals);
$this->addGrandTotals($totals);
return $this->getCollection()->getReport($from, $to);
}
}
app/code/local/Company/ModuleName/Block/Adminhtml/ModuleName.php
<?php
Class Company_ModuleName_Block_Adminhtml_ModuleName Extends Mage_Adminhtml_Block_Widget_Grid_Container
{
public function __construct()
{
$this->_controller = 'adminhtml_modulename';
$this->_blockGroup = 'modulename';
$this->_headerText = Mage::helper('modulename')->__(' Module Name Report');
parent::__construct();
$this->_removeButton('add');
}
}
app/code/local/Company/ModuleName/Block/ModuleName.php
<?php
Class Company_ModuleName_Block_ModuleName Extends Mage_Core_Block_Template
{
public function _prepareLayout()
{
return parent::_prepareLayout();
}
public function getModuleName()
{
if (! $this->hasData('modulename')) $this->setData('modulename', Mage::registry('modulename'));
return $this->getData('modulename');
}
}
app/code/local/Company/ModuleName/controllers/Adminhtml/ModuleNameController.php
<?php
Class Company_ModuleName_Adminhtml_ModuleNameController Extends Mage_Adminhtml_Controller_Action
{
protected function _initAction()
{
$this->loadLayout();
return $this;
}
public function indexAction()
{
$this->_initAction()->renderLayout();
}
public function exportCsvAction()
{
$this->_sendUploadResponse('modulename.csv', $this->getLayout()->createBlock('modulename/adminhtml_modulename_grid')->getCsv());
return $this;
}
public function exportXmlAction()
{
$this->_sendUploadResponse('modulename.xml', $this->getLayout()->createBlock('modulename/adminhtml_modulename_grid')->getXml());
return $this;
}
protected function _sendUploadResponse($fileName, $content, $contentType='application/octet-stream') {
$response = $this->getResponse();
$response->setHeader('HTTP/1.1 200 OK', '');
$response->setHeader('Pragma', 'public', true);
$response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
$response->setHeader('Content-Disposition', 'attachment; filename=' . $fileName);
$response->setHeader('Last-Modified', date('r'));
$response->setHeader('Accept-Ranges', 'bytes');
$response->setHeader('Content-Length', strlen($content));
$response->setHeader('Content-type', $contentType);
$response->setBody($content);
$response->sendResponse();
exit;
}
}
app/code/local/Company/ModuleName/etc/config.xml
<?xml version='1.0'?>
<!--
/**
* @category Company
* @package Company_ModuleName
* @author Jd Daniel
*/
-->
<config>
<modules>
<Company_ModuleName>
<version>0.1.0</version>
</Company_ModuleName>
</modules>
<admin>
<routers>
<modulename>
<use>admin</use>
<args>
<module>Company_ModuleName</module>
<frontName>modulename</frontName>
</args>
</modulename>
</routers>
</admin>
<adminhtml>
<menu>
<report>
<children>
<customers>
<children>
<modulename translate='title' module='modulename'>
<title> Module Name Report</title>
<action>modulename/adminhtml_modulename</action>
</modulename>
</children>
</customers>
</children>
</report>
</menu>
<acl>
<resources>
<all>
<title>Allow Everything</title>
</all>
<admin>
<children>
<report>
<children>
<customers>
<children>
<modulename translate='title' module='modulename'>
<title> Module Name Report</title>
<action>modulename/adminhtml_modulename</action>
</modulename>
</children>
</customers>
</children>
</report>
</children>
</admin>
</resources>
</acl>
<layout>
<updates>
<modulename>
<file>modulename.xml</file>
</modulename>
</updates>
</layout>
</adminhtml>
<global>
<models>
<modulename>
<class>Company_ModuleName_Model</class>
<resourceModel>modulename</resourceModel>
</modulename>
</models>
<resources>
<modulename_setup>
<setup>
<module>Company_ModuleName</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</modulename_setup>
<modulename_write>
<connection>
<use>core_write</use>
</connection>
</modulename_write>
<modulename_read>
<connection>
<use>core_read</use>
</connection>
</modulename_read>
</resources>
<blocks>
<modulename>
<class>Company_ModuleName_Block</class>
</modulename>
</blocks>
<helpers>
<modulename>
<class>Company_ModuleName_Helper</class>
</modulename>
</helpers>
</global>
</config>
app/code/local/Company/ModuleName/Helper/Data.php
<?php
Class Company_ModuleName_Helper_Data Extends Mage_Core_Helper_Abstract
{
// ....
}
app/code/local/Company/ModuleName/Model/ModuleName.php
<?php
Class Company_ModuleName_Model_ModuleName Extends Mage_Reports_Model_Mysql4_Order_Collection
{
public function __construct()
{
parent::__construct();
$this->setResourceModel('sales/order_item');
$this->_init('sales/order_item','item_id');
}
public function setDateRange($from, $to)
{
$this->_reset();
$this->getSelect()
->joinInner(array(
'i' => $this->getTable('sales/order_item')),
'i.order_id = main_table.entity_id'
)
->where('i.parent_item_id is null')
->where("i.created_at BETWEEN {$from} AND {$to}")
->where('main_table.state = \'complete\'')
->columns(array('ordered_qty' => 'count(distinct main_table.entity_id)'));
// uncomment next line to get the query log:
// Mage::log('SQL: '.$this->getSelect()->__toString());
return $this;
}
public function setStoreIds($storeIds)
{
return $this;
}
}
app/design/adminhtml/default/default/layout/modulename.xml
<?xml version='1.0'?>
<layout version='0.1.0'>
<modulename_adminhtml_modulename_index>
<reference name='content'>
<block type='modulename/adminhtml_modulename' name='modulename' />
</reference>
</modulename_adminhtml_modulename_index>
</layout>
app/etc/modules/Company_ModuleName.xml
<?xml version='1.0'?>
<config>
<modules>
<Company_ModuleName>
<active>true</active>
<codePool>local</codePool>
</Company_ModuleName>
</modules>
</config>