5

After twitter conversation with Brandon Kelly, is it possible to implement something similar to the following?

craft.entries.section("mySection").sum("myCustomField")
6

You could do this with a plugin. Create a Variable class with a function called sum(), which accepts an ElementCriteriaModel, passes it to ElementsService::buildElementsQuery(), and then replaces the SELECT value on the resulting DbCommand object:

<?php
namespace Craft;

class FooVariable
{
    public function sum(ElementCriteriaModel $criteria, $column)
    {
        $query = craft()->elements->buildElementsQuery($criteria);

        if ($query)
        {
            return $query
                ->select("SUM({$column})")
                ->group(null)
                ->queryScalar();
        }
    }
}

With that in place, you can do this in your templates:

{% set entries = craft.entries.section("mySection") %}
{% set sum = craft.foo.sum(entries, "field_myCustomField") %}

Note that you will need to pass in the field’s full column name (with that “field_” prefix) rather than just its handle. You can figure that out by looking at your craft_content table (or craft_matrixcontent_matrixfieldhandle if it’s a Matrix field). It would have been possible to get the code to be smart enough to figure the column name out for itself, but this way is a bit simpler.

2
  • 2
    Perfect. The only thing I had to change slightly was the return from return $query->select("SUM({$column})")->queryScalar(); to return $query->select("SUM({$column})")->group(null)->queryScalar(); So I could get the complete total for what I needed Aug 7 '14 at 13:15
  • Perfect ! I confirm the ->group(null) addition to make the total.
    – migswd
    Nov 6 '16 at 11:43
3

In Craft 3 you can do this without a plugin:

{% set hours = craft.entries
    .section('channelTimetracking')
    .sum('field_myCustomField')
?? null %}

Details in the docs.

1
  • I just discovered, if you are summing matrix fields, you need to do this: field_matrixBlockName_fieldName.
    – 4midori
    Aug 18 '20 at 21:14

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.