0

In a plugin, I've been advised to try to use craft built-in services instead of direct db queries. So can anyone help with this: For an entry type that includes a categories field, how to get all the categories related to an entry?

I found this:

$entry = craft()->entries->getEntryById($entryId);

So I suppose this might work as well:

$category = craft()->categories->getCategoryById($categoryId);

But I can't find anything intelligible to me under the relations service.

Thanks for any help.

EDIT: On a related note, I see here that in twig you can do this:

{% for entry in craft.entries.section('news').limit(10) %}
<article>
    <h1><a href="{{ entry.url }}">{{ entry.title }}</a></h1>
    {{ entry.summary }}
    <a href="{{ entry.url }}">Continue reading</a>
</article>
{% endfor %}

Whereby Craft/Twig does all the work to find and return the 'summary' field related to each entry. Is there any php statement like this next confused one, following which I could get the categories related to each event?

$events = craft()->entries.section('events').start('<=$toDateYmd').end('OR', '>=$fromDateYmd', '').status('publish');
foreach ($events as $event)
   $categories = $event.category;

Thank you!

1
  • I actually have a lot of questions about interacting with the database. The Craft documentation on database queries is pretty sparse, mainly pointing to yiiframework.com which I find quite unintelligible. Any advice just for examples of db queries and updates at all?
    – kr37
    May 27, 2015 at 23:55

2 Answers 2

3

If you have an EntryModel and know the category field's handle, you don't really need a service:

$categories = $entry->categoryFieldHandle;

In other cases, you can construct an ElementCriteriaModel to search for related elements (categories, entries, users or assets), using a number of different variables. Easy example to get related categories from an entry ID:

$criteria = craft()->elements->getCriteria(ElementType::Category);
$criteria->relatedTo = array($entryId);
$categories = craft()->elements->findElements($criteria);
2
  • Thank you mmikkel, I had come to a similar conclusion. I appreciate the second example, as that may come in handy later. Is craft()->elements->findElements($criteria) different from $criteria->find() ?
    – kr37
    May 28, 2015 at 7:25
  • Not AFAIK – $criteria->find() actually calls craft()->elements->findElements() (which refers to the ElementsService. Doesn't really matter which method you use, in my experience. $criteria->find() is shorter :) May 28, 2015 at 8:17
1

OK, here is what I worked out, through hours of trial and error. A hint came from the docs:

This should be the starting point any time you want to fetch elements in Craft.

$criteria = craft()->elements->getCriteria(ElementType::Entry);

$criteria->section = 'news';

$entries = $criteria->find();

In my plugin's services file this produces the desired results:

// Set up the criteria
$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section = 'events';
$criteria->startDate = array("<=$toDateYmd", NULL);
$criteria->endDate = array(">=$fromDateYmd", NULL);

$entries = $criteria->find();  //Do the query

foreach ($entries as $entry) {
    $categories = $entry->categories;
    echo "<br>title: $entry->title Start: $entry->startDate<br><pre>";
    echo "Categories:</br>";
    foreach ($categories as $k => $v) echo " [$k] => $v<br>";
}

When adding the criterias, each array is basically doing an 'OR'. So it's if startDate <= $toDateYmd OR startdate = NULL. I just happen to need to accept NULL as a value here.

If anyone has a better way of doing it, please let me know, but code-wise this seems quite concise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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