I found it is possible to do a rewrite on a core class that does not actually exist....
Usage case example:
I am creating a reCaptcha module that integrates google recaptcha into magento's core captcha system.
In the core captcha you have the ability to state a 'type', as can be seen in the config.xml
of Mage_Captcha
<default>
......
<admin>
<captcha>
<type>zend</type> <<<<<<<<<<<<<<< specify a captcha type (model)
<enable>0</enable>
<font>linlibertine</font>
<mode>after_fail</mode>
<forms>backend_forgotpassword</forms>
<failed_attempts_login>3</failed_attempts_login>
<failed_attempts_ip>1000</failed_attempts_ip>
<timeout>7</timeout>
<length>4-5</length>
<symbols>ABCDEFGHJKMnpqrstuvwxyz23456789</symbols>
<case_sensitive>0</case_sensitive>
<always_for>
<backend_forgotpassword>1</backend_forgotpassword>
</always_for>
</captcha>
</admin>
......
</default>
so in my module I extend the core functionality and added a new type called 'recaptcha'
However, the developer of that core module kinda locked the model location down to exist within the Mage_Captcha
namespace, as can be seen in the helper class of that module
/**
* Get Captcha
*
* @param string $formId
* @return Mage_Captcha_Model_Interface
*/
public function getCaptcha($formId)
{
if (!array_key_exists($formId, $this->_captcha)) {
$type = $this->getConfigNode('type');
$this->_captcha[$formId] = Mage::getModel('captcha/' . $type, array('formId' => $formId));
}
return $this->_captcha[$formId];
}
so Mage_Captcha_Model_Recaptcha
does not actually exist, which means I cannot use this....BUT, if, I place a rewrite directive in my module for that class/file, to a model class in my module, I can intercept the model instantiation, and successfully instantiate my class.
<captcha>
<rewrite>
<recaptcha>MyNamespace_MyModule_Model_Recapthca</recaptcha>
</rewrite>
</captcha>
Considering how rewrites work, I do think there is not any need for magento's rewrite system to check (or care) that a file exists to rewrite it.
Magento get the rewrite directive, and instantiates the new model class instead of the original (even if it does not exist)
So, is this a bug, or a feature? Should I not depend on this ability? It does, however, open up some possibilities on extending some poorly written core functionality (like this captcha system)
EDIT: I released a module that resulted in this question happening. The module is a nice drop-in replacement of core captcha with googles reCaptcha