Magic methods are implemented via Varien_Object
class.
public function __call($method, $args)
{
switch (substr($method, 0, 3)) {
case 'get' :
//Varien_Profiler::start('GETTER: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
$data = $this->getData($key, isset($args[0]) ? $args[0] : null);
//Varien_Profiler::stop('GETTER: '.get_class($this).'::'.$method);
return $data;
case 'set' :
//Varien_Profiler::start('SETTER: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
$result = $this->setData($key, isset($args[0]) ? $args[0] : null);
//Varien_Profiler::stop('SETTER: '.get_class($this).'::'.$method);
return $result;
case 'uns' :
//Varien_Profiler::start('UNS: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
$result = $this->unsetData($key);
//Varien_Profiler::stop('UNS: '.get_class($this).'::'.$method);
return $result;
case 'has' :
//Varien_Profiler::start('HAS: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
//Varien_Profiler::stop('HAS: '.get_class($this).'::'.$method);
return isset($this->_data[$key]);
}
throw new Varien_Exception("Invalid method ".get_class($this)."::".$method."(".print_r($args,1).")");
}
You'll need to either extend that class or any other class which extends from Varien_Object
like Mage_Core_Model_Abstract
for example. You are not required to define any variables or methods in your model as long as your method starts with get
, set
, uns
and has
, that is assuming you want them to work as magic methods.
So you can write something like this:
$model = Mage::getModel('namespace_module/sample');
$model->setSomeData('Hello');
echo $model->getSomeData();
If you do Zend_Debug::dump($model);
you'll notice that your data is stored in _data
property which is declared in Varien_Object
class.
Example:
object(Namespace_Module_Model_Sample)#128 (7) {
["_data":protected] => array(1) {
["some_data"] => string(5) "Hello"
}
["_hasDataChanges":protected] => bool(true)
["_origData":protected] => NULL
["_idFieldName":protected] => NULL
["_isDeleted":protected] => bool(false)
["_oldFieldsMap":protected] => array(0) {
}
["_syncFieldsMap":protected] => array(0) {
}
}
Namespace root is your most likely problem. PhpStorm absolutely supports the feature you're looking for, and it should work out of box.
Make sure your project encompasses the entire source code, then tell PhpStorm where to go looking, if it wasn't able to work it out on its own. See: https://www.jetbrains.com/help/phpstorm/2016.1/configuring-php-namespaces-in-a-project.html#d140255e161
Configuring Namespace Roots Manually
Open the Settings / Preferences Dialog by choosing File | Settings for Windows and Linux or PhpStorm | Preferences for OS X, and click Directories under Project:.
The right-hand pane of the Directories page that opens shows all the content roots configured in the project. As a rule, there is one content root which is the root folder of the current project.
The central pane shows all the folders under the selected content root. Select the folder to be treated as the namespace root and click Sources.
It is perfectly fine to configure multiple source roots: PhpStorm will treat each of those as a namespace root and provide namespace hints for files underneath them. For example every subfolder of a vendor folder can be marked as a namespace root. In the example below, we have two namespace roots: one for the actual application and one for a vendor folder
At minimum, you want to set the 'vendor' folder as Sources, plus the app/code folder if it exists. Under normal circumstances, every module (and namespace) should be within those two locations.
Best Answer
most of the issues get resolved if you use n98-magerun to generate the phpstorm meta file https://github.com/netz98/n98-magerun#development-ide-support
If there are cases where this does not happen correctly, please report them, so it can get extended :)