Create Structure on Plugin Install I'm trying to create a structure using onBeforeInstall() that will be ready for a client to use after the plugin is installed.

Here's my code for onBeforeInstall():

public function onBeforeInstall()
{
    $section = new SectionModel();
    $section-&gt;name = 'Demo';
    $section-&gt;handle = 'demo';
    $section-&gt;type = 'structure';
    $section-&gt;hasUrls = 1;
    $section-&gt;template = 'demo/page';
    $section-&gt;enableVersioning = 1;
    $locale = craft()-&gt;sections-&gt;getSectionLocales(1)[0];
    $locale-&gt;urlFormat = 'demo/{slug}';
    $locale-&gt;nestedUrlFormat = '{parent.uri}/{slug}';
    $section-&gt;setLocales([ $locale ]);

    $response = craft()-&gt;sections-&gt;saveSection($section);
    if ($response) {
        var_dump("IT WORKED!");
        var_dump($response);
    } else {
        var_dump("nope.avi");
        var_dump($response);
    }
}


Unfortunately I get a CDbException


  CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`craft`.`craft_sections_i18n`, CONSTRAINT `craft_sections_i18n_locale_fk` FOREIGN KEY (`locale`) REFERENCES `craft_locales` (`locale`) ON DELETE CASCADE ON UPDATE CASCADE). The SQL statement executed was: INSERT INTO `craft_sections_i18n` (`sectionId`, `locale`, `enabledByDefault`, `urlFormat`, `nestedUrlFormat`, `dateCreated`, `dateUpdated`, `uid`) VALUES (:row0_col0, :row0_col1, :row0_col2, :row0_col3, :row0_col4, :row0_col5, :row0_col6, :row0_col7). Bound with :row0_col0='7', :row0_col1=0, :row0_col2=1, :row0_col3='demo/{slug}', :row0_col4='{parent.uri}/{slug}', :row0_col5='2015-06-09 20:33:00', :row0_col6='2015-06-09 20:33:00', :row0_col7='864207ba-6e43-46cf-9fdb-3a72cda4c2df'`


I was basing my code loosely on this Stack Exchange question and answer, but for some reason I can't get structures to cooperate.

I think I'm not setting the locale properly.  Is there a better way to set the locale, or am I overlooking something else?
I haven't used locales before so i'm not entirely sure, but when I looked in the craft service that saves a section there is a bit that looks like:

foreach ($sectionLocales as $localeId =&gt; $sectionLocale)
...


Which I assume then means your array needs to look like this:

array(
 'en' =&gt; // model
)


Whereas yours was looking like this:

array(
 0 =&gt; // model
)


So craft was seeing 0 as the locale id and it was failing.

So I managed to get this to work by using the following code:

public function onBeforeInstall()
{
  // Get the current locales ID
  $currentLocale = craft()-&gt;locale-&gt;getId();

  $section = new SectionModel();
  $section-&gt;name = 'Demo';
  $section-&gt;handle = 'demo';
  $section-&gt;type = 'structure';
  $section-&gt;hasUrls = 1;
  $section-&gt;template = 'demo/page';
  $section-&gt;enableVersioning = 1;

  // Index the locales by their ID e.g en returns array
  $locales = craft()-&gt;sections-&gt;getSectionLocales(1, 'locale');

  // Target the locale we want by the key in the array
  $locales[$currentLocale]-&gt;urlFormat = 'demo/{slug}';
  $locales[$currentLocale]-&gt;nestedUrlFormat = '{parent.uri}/{slug}';

  $section-&gt;setLocales($locales);

  $response = craft()-&gt;sections-&gt;saveSection($section);
}


The Demo section was added and I got the 'IT WORKED' response, I hope that helps!

Edit

I suppose if you didn't want all the locales to be saved to a section you could just do something like:

$specificLocales = array();

// After setting the locale attributes
$specificLocales[$currentLocale] = $locales[$currentLocale];

$section-&gt;setLocales($specificLocales);