You're not going to get out of this without a little debugging. The following applies to Magento CE, but should be relevant for Magento EE. Also, this post summarizes a lot of material found in my Magento Dispatch series. If you want to really engage in some bottom up debugging, start there.
To start, most of the Magento problems I see boil down to "I was really sure this one thing was X, but it was actually Y". Even if you're absolutely sure about something I tell you to check, make sure you actually check it.
The routing for Magento's homepage is handled by the Mage_Core_Controller_Varien_Router_Standard
object. The first key part is this line
#File: app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
$p = explode('/', $this->_getDefaultPath());
The _getDefaultPath
method looks at your Magento store config for the set value.
protected function _getDefaultPath()
{
return Mage::getStoreConfig('web/default/front');
}
which is the configuration that corresponds to
System -> Configuration -> Web -> Default Pages -> Default Web URL
Tripple check that this value is set to the string
`cms`
and that your core_config_data
table
select * from core_config_data where path = 'web/default/front';
doesn't contain any unexpected scoped values.
Once you've done the above, add some temporary debugging code to peek at the value of $p
after that call.
$p = explode('/', $this->_getDefaultPath());
var_dump($p);
//or
Mage::Log($p);
//or
file_put_contents('/tmp/test.log',"$p\n",FILE_APPEND);
You should see output something like this
array (size=1)
0 => string '' (length=0)
array (size=1)
0 => string 'cms' (length=3)
The reason you have two items being dumped/logged is the match
method is shared between the admin router and the standard router object. If the second item isn't a one element array with cms
, that's your problem. Figure out what that's not happening, and you'll be on your way to solving the problem.
Assuming that's not the problem, Magento should now dispatch to the indexAction
method in the IndexController.php
file in the Mage_Cms
module. Ensure this is the case by adding the following two lines to the start of indexAction
#File: app/code/core/Mage/Cms/controllers/IndexController.php
public function indexAction($coreRoute = null)
{
$pageId = Mage::getStoreConfig(Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE);
if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
$this->_forward('defaultIndex');
}
}
You should see Mage_Cms_IndexController::indexAction
dumped to the browser window. If this doesn't happen, then there's something about your system that's preventing standard routing from being used — jump back up into the match
method and figure out why $controller
, $controllerClassName
, $controllerInstance
, and $action
variables don't point to the indexAction
method in the IndexController.php
file in the Mage_Cms
module. (If this is the case, say so in the comments and I'll provide an update debugging scanrio for this)
Assuming you are being routed to this controller file and action correctly, remove the
var_dump(__METHOD__);
exit;
and instead add a new var_dump
$pageId = Mage::getStoreConfig(Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE);
var_dump($pageId);
Magento allows you to configure the identifier of the page that should be used as the home page. The Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE
should corresponds with the store config path web/default/cms_home_page
, which corresponds with the
System -> Configuration -> Web -> Default Pages -> CMS Home Page
section. This is where you tell Magento which CMS page you want to use as your homepage. You should see something like
string 'home' (length=4)
or
string 'about-magento-demo-store' (length=4)
or etc. dumped to your screen. This is the CMS home page identifier. If you're setting an unexpected value, try running the following
select * from core_config_data where path = 'web/default/cms_home_page';
to check for scoped values. Regardless of what you CMS Home Page ID is, check for the page's existence with the following SQL statement (assuming a value of home
).
select * from cms_page where identifier = 'home';
If Magento can't find the configured page in your system, it will forward to the 404 page. You can see that with the following code in indexAction
if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
$this->_forward('defaultIndex');
}
If renderPage
returns false
, then we're forwarded to the defaultIndexAction
method which renders the 404 page.
public function defaultIndexAction()
{
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
$this->getResponse()->setHeader('Status','404 File not found');
$this->loadLayout();
$this->renderLayout();
}
That should be enough to find 90% of your "no route to homepage" problems, and point you in a debugging direction for the other 10%.
Welcome to Magento.StackExchange!
Unfortunately, there is no out-of-box module that will do this for you.
I'd highly encourage you to reconsider this as an option. Your users are not stupid (no matter how stupidly they behave) - many, many years of eCommerce analysis has shown me that, nearly 80% of the time, users reaching a 404 will hit the on-site-search bar within seconds. Put your effort into fixing up your site search with better categorization (read: keyword stuffing).
Google indexes aren't forever. If you're afraid of 404s, consider sprucing up your 404 page itself. Increase your conversion potential by offering a 5-10% discount coupon to those inconvenienced by hitting a 404. Or, better yet, don't disable product pages. Rather, disable the ability to purchase (e.g. set as out of stock) and provide a static block / link that links to the relevant page/category.
I don't care, just give me codes because internets:
At it's simplest coding a module with an observer that will handle this for you is trivial:
Event designation in config.xml:
<global>
<events>
<controller_action_postdispatch_catalog_product_view>
<observers>
<yourmodule_capcpv>
<class>YourCompany_YourModule_Model_Observer</class>
<method>catalogProductViewPostdispatch</method>
</yourmodule_capcpv>
</observers>
</controller_action_postdispatch_catalog_product_view>
</events>
</global>
app/code/local/YourCompany/YourModule/Model/Observer.php:
<?php
class YourCompany_YourModule_Model_Observer
{
public function catalogProductViewPostdispatch($observer)
{
$controller = $observer->getEvent()->getControllerAction();
$product = Mage::registry('current_product');
if($product->getStatus()!=Mage_Catalog_Model_Product_Status::STATUS_ENABLED){
$action->getResponse()->setRedirect(/* your redirect URL here with Mage::getUrl() */);
}
}
}
Best Answer
I had a problem that responded well to commenting out the line you suggest too.:
so this got me thinking to look for anything using that event, so i did a grep on app/code for catalog_controller_product_view
not, much, considering the first one is just that which has the line we commented. then i see something in Reports, and that jogs my memory... i didnt think it was necessary but i had emptied the report_* tables during a database merge, this must have been it,
so after restoring those tables from a backup its working again even with the line uncommented... !