6

I have a webhook that fetches an entry, modifies one of its custom Text field values and then saves the entry. However there is also a required Categories field on the entry, and when I do this, I get a validation error because the Categories field is blank.

Here’s the relevant code:

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

$entry->setContentFromPost(array(
    'myTextField' => $newValue
));

// Let's see if it saves.
// Field validation should happen automatically
if (craft()->entries->saveEntry($entry))
{
    Craft::log('Entry updated (ID: '.$entry->id.').');
}
else
{
    Craft::log('Could not updated the entry (ID: '.$entry->id.').', LogLevel::Error);
}

How do I save the entry without losing its existing Categories field value?

2 Answers 2

5

Update - Craft 3

This has been fixed. The relational field will retain its original value when an entry is re-saved.

You no longer need to apply a workaround to get the expected behavior.


Original - Craft 2

This is, admittedly, super awkward right now. To prevent a relational field from losing its value when saving an entry, you have to explicitly set its value to null:

$entry->setContentFromPost(array(
    'myCategoriesField' => null
    // ...
));

However, this only works for relational fields that aren’t set to Required. If the field is set to Required, you have to just re-set the field to the same element IDs that were already selected:

$entry->setContentFromPost(array(
    'myCategoriesField' => $entry->myCategoriesField->ids()
    // ...
));

(FWIW, this will stop being awkward in Craft 3, as we done some major refactoring under the hood to fix issues like this.)

6
  • Ideally I don't want to change at all as it's already set. I only want to change the stock level and leave everything else as is, but having the Category as a required field is not letting me do that. Aug 24, 2015 at 14:08
  • @divinemonkey Just updated your question and my answer after getting some clarification on it from carlcs. Aug 24, 2015 at 14:19
  • Got it. All working now. Thanks, and to you also @carlcs Aug 25, 2015 at 9:28
  • @BrandonKelly Is there a way to easily re-populate all the existing content an entry already has, without knowing exactly what fields it has? I'm trying to make a generic function that can be used across sections and would prefer not to have to manually specify all required relational fields, but do a single function call to cover every possible case. Dec 15, 2015 at 13:17
  • 1
    @BrandonKelly Sorry, not sure I follow you...? How does that help me exactly? Dec 16, 2015 at 10:05
1

I'm probably missing something here, but can't you just query for the entry model and only modify the field you want to change?

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->id = 1;
$entries = $criteria->first();

if ($entry)
{
    $entry->setContentFromPost(array(
        'fieldToChange' => 'newValue'
    ));

    // Validate the entry model here if necessary

    craft()->entries->saveEntry($entry);
}
8
  • I've updated my original post as a response to see if this would still work. Aug 24, 2015 at 3:06
  • Yes, should really be the same. Have a look at the full gist I created for you gist.github.com/carlcs/ef4664ceb281db7068fd. Test that code and tell me if you're still getting errors in the log! :)
    – carlcs
    Aug 24, 2015 at 6:59
  • Unfortunately I am still getting the same error. 2015/08/24 09:42:43 [warning] [application] Craft\ContentModel->productCategory failed validation: Product Category cannot be blank. I am tempted to remove it has a required field currently. Seems the easiest solution. Aug 24, 2015 at 9:48
  • And it did validate / saved without errors from the CP when you created that entry? Is there a category selected at all for that entry?
    – carlcs
    Aug 24, 2015 at 9:56
  • The webhook did complete with no errors, no stock update in the backend though and the Craft log receives that error. Yes, it is defined as Hardware. Aug 24, 2015 at 10:06

Your Answer

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

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