7

Initially I was doing $entry->getContent()->getAttributes(), but noticed my Matrix fields were all null.

What is the right way to do this?

I see that $entry->myMatrixField gives me the ElementCriteriaModel for my Matrix that I need, I thought that would be the same as using `getAttribute('myMatrixField'), but i guess not.

3 Answers 3

5

ContentModel will only have the values in the actual content table, and the values that are actually there still may not be what you’re after, because accessing those values directly won’t give the field types a chance to do any preprocessing on their data.

So the best way to reliably get an array of all of an element’s custom field content is to go through its Field Layout, via BaseElementModel::getFieldLayout():

// Craft 2
$values = array();

foreach ($element->getFieldLayout()->getFields() as $fieldLayoutField)
{
    // $fieldLayoutField is a FieldLayoutFieldModel, *not* a FieldModel
    // http://buildwithcraft.com/classreference/models/FieldLayoutFieldModel
    // so get the actual FieldModel here
    $field = $fieldLayoutField->getField();

    // Now get the prepped field value
    $value = $element->getFieldValue($field->handle);

    $values[$field->handle] = $value;
}

Update: As of Craft 3, you can get all the custom field values using getFieldValues():

$values = $element->getFieldValues();
4
  • Is there a twig equivalent of this and will it get everything from an entry whatever it contains?
    – Spoeken
    Commented Dec 2, 2014 at 18:40
  • @Spoeken Same methods; different syntax: craftcms.stackexchange.com/questions/4753/… Commented Dec 3, 2014 at 13:44
  • @BrandonKelly Is this answer correct for Craft 3 and Craft 4? Or is there a different way to do this now? I'm having the same problem here in 2022
    – vlasits
    Commented May 23, 2022 at 20:21
  • @Spoeken This was for Craft 2. Updated the answer for Craft 3+. Commented May 24, 2022 at 20:56
2

I had the same problem a couple of weeks ago: apparently there isn't a simple function that can be called as getAttributes only returns data from the content table.

I wrote the code below to get data for all matrix fields within an entry, but later on I realised that there are other fields which appear null from getAttributes such as asset and entry fields.

Anyone else have a rock-solid method for all data?

$content = $entry->getContent();

$data = $content->getAttributes(null,true);

    // Getting content / attributes doesn't appear to work for Matrix fields? - get content and re-populate data array
    $matrixFields = craft()->db->createCommand()->select(array('handle'))->where( array('type' => 'Matrix') )->from('fields')->queryAll();

    foreach( $matrixFields as $matrix )
    {
        $handle = $matrix['handle'];

        if( $entry->$handle )
        {
            $attributes = array();
            foreach( $entry->$handle as $matrix )
            {
                $attr =  $matrix->getContent()->getAttributes();

                // Attribute Formatting (this is formatting for my use-case - feel free to amend as you need)
                unset( $attr['id'] , $attr['elementId'] , $attr['locale'] , $attr['title'] );
                $attr = array_merge( $attr , array("___type" => $matrix->type->handle ) );

                $attributes[] = $attr;
            }
            $data[$handle] = $attributes;
        }
    }
1

Reference: What is getContent() / the ContentModel, and how do I use it to get and set custom field values?

In my case, I wanted to get all attributes, and all content attributes. Here's my approach: http://gist.github.com/timkelty/2a221ac232e5ecf1b090

Curious to see if there are alternate solutions, though.

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.