6

When trying to fetch an entry with special characters in the title, it doesn't seem to match.

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->title = "Title,with,commas";
$entry = $criteria->first();

I've also tried a few other characters such as #, %, and $ with the same result - $entry is empty.

9

Have a look at DbHelper::parseParam docs:

If the $value is a string, it will automatically be converted to an array, split on any commas within the string (via ArrayHelper::stringToArray()). If that is not desired behavior, you can escape the comma with a backslash before it.

To escape the comma and other characters treated as special in DbHelper::parseParam use the DbHelper::escapeParam helper:

$criteria->title = DbHelper::escapeParam("Title, with, commas");
2
  • Thats perfect @carlcs, exactly what I needed - nice one!
    – crawf
    May 21 '15 at 12:13
  • Updating this answer for Craft 3: use craft\helpers\Db; ... Db::escapeParam(...); Jul 1 '20 at 12:03
2

You have to escape your commas, or craft wil interpret that as if your searching for several titles. Notice the where clause, "contenttitle1, contenttitle2, contenttitle3".

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->title = 'Title,with,commas';
$entry = $criteria->first();

// will result in this query:
SELECT <a bunch of fields>
FROM `craft_elements` `elements`
JOIN `craft_elements_i18n` `elements_i18n` ON elements_i18n.elementId = elements.id
JOIN `craft_content` `content` ON content.elementId = elements.id
...
WHERE (((((elements_i18n.locale = :locale) AND (content.locale = :locale)) AND (elements.archived = 0)) AND ((elements.enabled = 1) AND (elements_i18n.enabled = 1) AND (entries.postDate <= '2015-05-21 09:08:27') AND ((entries.expiryDate is null) OR (entries.expiryDate > '2015-05-21 09:08:27')))) AND ((content.title=:contenttitle1) OR (content.title=:contenttitle2) OR (content.title=:contenttitle3))) AND (elements_i18n.enabled = 1)
GROUP BY `elements`.`id`
ORDER BY `lft`, `postDate` DESC LIMIT 1. Bound with :locale='en', :contenttitle1='Title', :contenttitle2='with', :contenttitle3='commas')

Use this

$criteria->title = 'Title\,with\,commas';
1
  • I thought this might have been the case - thanks!
    – crawf
    May 21 '15 at 12:13
1

I'm not entirely sure why $criteria->title doesn't work (maybe someone can shed some light), but I did try these other two methods and they both pulled an entry with special characters like you describe above.

$criteria->getContent()->title = 'Some$other$message';

$criteria->search = 'Some$other$message';`

I guess $criteria->getContent()->title is more explicit and more what you need, as search would match more than just the titles.

1
  • 1
    Thanks Alec - I would use search as its likely easier, but in my case, performance really matters, and its a lot slower than searching directly by handle.
    – crawf
    May 21 '15 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.