3

I've made a plugin that let's you import Entries from a CSV file and I'm working through adding localization (Sites) support to it, but I can't figure out the right way to enable an Entry for a second Site.

$entry = New Entry();
$entry->authorId = $authorId;
$entry->sectionId = $sectionId;
$entry->typeId = $typeId;
$entry->enabled = true;
$entry->title = $title;
$entry->Slug = $slug;
$entry->siteId = $firstSiteId;

$entry->setFieldValues($attrs);

Craft::$app->elements->saveElement($entry);

Everything above works, but it's this next part which I can't get to work properly. It just throws errors about violating the constraint for a duplicate element ID/site ID pair:

$entry->siteId = $secondSiteId;
Craft::$app->elements->saveElement($entry);

I also tried this, but the query never returns any results:

$findTheNewEntry = Entry::find()
    ->sectionId($sectionId)
    ->id($entry->id)
    ->status(null)
    ->siteId($secondSiteId)
    ->one();

$findTheNewEntry->enabled = true;
Craft::$app->elements->saveElement($findTheNewEntry);

I wish it was as simple as being able to provide an array or such for ->siteId but I know that's wrong.

3

I was able to get this working with this:

$findTheNewEntry = Entry::find()
    ->sectionId($sectionId)
    ->id($entry->id)
    ->anyStatus()
    ->siteId($secondSiteId)
    ->one();

$findTheNewEntry->enabledForSite = true;
Craft::$app->elements->saveElement($findTheNewEntry);

When creating a new entry via ->saveElement(), Craft automatically creates entries for all sites that have that section enabled. The issues I was having were because status and enabledForSite are different, and I needed to use ->anyStatus() to retrieve an element that was globally enabled when I created it but not enabled for the second site yet. Once that was retrieved, I could enable that entry for the second site as well.

1

My best guess is, that the duplicate element/ID pair gets thrown because after saving the first entry, the second site's entry already exists. This is because of the default behaviour of the saveElement() method:

public function saveElement(ElementInterface $element, bool $runValidation = true, bool $propagate = true): bool

The third attribute (propagate) is set to true by default, resulting in Craft propagating your entry for site 1 to all other sites, depending on the propagation settings of that specific section. So, you could let this happen (and be sure to check what the default propagation settings for the section are), or tell saveElement() to not propagate:

# Save element without propagation, but with validation
Craft::$app->getElements()->saveElement($element, true, false)

Having said this, are you aware that, for Craft 3, you can now use the free and first party Feed Me plugin to import CSV?

  • I didn't realize that Feed Me was now first party - when I looked at Feed Me last, it couldn't be configured to the mapping I needed. Even now - I'm not sure it's possible to map a single row in the CSV to specify creating one entries for 2+ Sites. – khamer Apr 11 at 12:39

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.