6

I'm a bit confused about the usage of these two. Let's say I want to create a new entry from a controller. For me, the nicer option would be to user something like this:

$entry = new EntryModel();
$entry->sectionId = 4;
$entry->typeId = 4;

$entry->setContent([
    'foo' => 'bar',
    'xyz' => '456', 
]);

craft()->entries->saveEntry($entry);

Somehow this is not working for me. Instead, I have to use the uglier version like this:

$entry = new EntryModel();
$entry->sectionId = 4;
$entry->typeId = 4;

$entry->getContent()->foo = 'bar';
$entry->getContent()->xyz = '123';

craft()->entries->saveEntry($entry);

Any ideas why the first example might be failing? Especially when working with more than two attributes, the first example would be way more easy to handle.

13

You should be using setContentFromPost() rather than setContent(), so that field types have a chance to prep the values that you are passing in.

See “What is getContent() / the ContentModel, and how do I use it to get and set custom field values?” for more info on how this stuff works.

6

I am just iterating on the previous answer to attempt to explain why this is happening. If you take a look at BaseElementModel.php at the setContent() method. You'll see that the core code is doing pretty much the exact thing as:

$entry->getContent()->setAttributes(array(
    'foo' => 'bar',
    'xyz' => '123'
));

The core confusion seems to be coming from a misunderstanding of how Yii models work. When a model as attributes defined, only those attributes can be set. Any other attribute will be ignored. I am not sure if you are trying to set attributes on a model that doesn't exist, but I used the following and it seems to work for me.

$entry = new EntryModel();
$entry->sectionId = 4;
$entry->typeId = 4;

// Works because title exists in the content model
$entry->setContent([
    'title' => 'bar'
]);

// foo and xyz do not exist in the content model, so attributes are ignored
$entry->setContent([
    'foo' => 'bar',
    'xyz' => '123'
]);

var_dump($entry->getContent()->getAttributes());exit();

The reason why the following works is because you using PHP to set a public property on an object instance. So if you are finding yourself having to rely on something like this, check to see if the attributes exist in the content model using var_dump or something similar.

$entry->getContent()->foo = 'bar';

You can see how the core method works here:

http://buildwithcraft.com/classreference/models/BaseElementModel#setContent-detail

  • thanks for the in-depth explanation. Obviously Brandons answer is also correct, not sure if I can accept two answers as correct? – Sidney Widmer Jan 26 '15 at 7:29
  • I upvoted Brandon's answer :). I would probably go for his answer being correct since he's the creator of Craft and knows the platform a lot better than I do. – Justin Kimbrell Jan 26 '15 at 22:50
4

Have you tried using that form of setting with this method instead?

$entry->setContentFromPost(['foo' => 'bar', 'xyz' => '123']);

There's also this method:

$entry->getContent()->setAttributes(array(
'foo' => 'bar',
'xyz' => '123'
));

As to the specific question of why doesn't setContent() work as expected, I can only guess that it may have to do with the values not being prepared properly.

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.