tags:

views:

58

answers:

1

Trying to load a product by it's name ("What are Tests?") fails even though the product exists.

$product = Mage::getModel('catalog/product')->loadByAttribute('name', 'What are Tests?');

It works for any other name though.

As Magento ultimately goes through PDO, would the "?" in the name be interpreted as a parameter and as I'm not passing any value for it, the ending query would actually be looking for "What are Tests" ... therefore not finding the product?

If so, how would I escape it?

Cheers!

+1  A: 

I'm not sure escaping it is possible. When you add an attribute filter with Magento (which is what you're doing above), it creates the where component using Zend's quoteInto method, and then adds the resulting string to a Zend Select object.

//create a full where clause
//In this case, $conditionSql = IF(_table_name.value_id>0, _table_name.value, _table_name_default.value) = 'What are Tests?'
$conditionSql = $this->_getAttributeConditionSql($attribute, $condition, $joinType);
...
//add that where clause to a Zend select object 
$this->getSelect()->where($conditionSql);

Then, when the Zend select gets converted to a string, it comes out as

IF(_table_name.value_id>0, _table_name.value, _table_name_default.value) = 'Product 7800'''

The problem is a full, not paramaterized where is getting added to the select. Its safe since _getAttributeConditionSql uses Zend's quoteInto method, but I'm pretty sure it means you're stuck if your where clause has a raw "?" mark in there (happy to be proven wrong on this) It's probably possible to do this by fiddling directly with resource model's select, but I'm not a fan of doing that with Magento.

Irrespective of all that, the following should allow you to work around this

$product = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('name',array('like'=>'What are Tests_'))
->getFirstItem();

The code above create a collection with a where clause that uses the single character wildcard "_" in place of a "?", and then plucks the first item off the top. Not ideal, but it should be a sufficient work around.

Alan Storm