/**
  * Saves a section.
  *
  * @param SectionModel $section
  * @throws \Exception
  * @return bool
  */
 public function saveSection(SectionModel $section)
 {
     $sectionRecord = $this->_getSectionRecordById($section->id);
     $isNewSection = $sectionRecord->isNewRecord();
     if (!$isNewSection) {
         $oldSection = SectionModel::populateModel($sectionRecord);
     }
     $sectionRecord->name = $section->name;
     $sectionRecord->handle = $section->handle;
     $sectionRecord->titleLabel = $section->titleLabel;
     $sectionRecord->hasUrls = $section->hasUrls;
     if ($section->hasUrls) {
         $sectionRecord->template = $section->template;
     } else {
         $sectionRecord->template = $section->template = null;
     }
     $sectionRecord->validate();
     $section->addErrors($sectionRecord->getErrors());
     // Make sure that all of the URL formats are set properly
     foreach ($section->getLocales() as $localeId => $sectionLocale) {
         if ($section->hasUrls) {
             $errorKey = 'urlFormat-' . $localeId;
             if (empty($sectionLocale->urlFormat)) {
                 $section->addError($errorKey, Craft::t('{attribute} cannot be blank.', array('attribute' => 'URL Format')));
             } else {
                 if (strpos($sectionLocale->urlFormat, '{slug}') === false) {
                     $section->addError($errorKey, Craft::t('URL Format must contain “{slug}”'));
                 }
             }
         } else {
             $sectionLocale->urlFormat = null;
         }
     }
     if (!$section->hasErrors()) {
         $transaction = craft()->db->beginTransaction();
         try {
             if (!$isNewSection && $oldSection->fieldLayoutId) {
                 // Drop the old field layout
                 craft()->fields->deleteLayoutById($oldSection->fieldLayoutId);
             }
             // Save the new one
             $fieldLayout = $section->getFieldLayout();
             craft()->fields->saveLayout($fieldLayout);
             // Update the section record/model with the new layout ID
             $section->fieldLayoutId = $fieldLayout->id;
             $sectionRecord->fieldLayoutId = $fieldLayout->id;
             $sectionRecord->save(false);
             // Now that we have a section ID, save it on the model
             if (!$section->id) {
                 $section->id = $sectionRecord->id;
             }
             // Might as well update our cache of the section while we have it.
             // (It's possilbe that the URL format includes {section.handle} or something...)
             $this->_sectionsById[$section->id] = $section;
             // Update the sections_i18n table
             $newLocaleData = array();
             if (!$isNewSection) {
                 // Get the old section locales
                 $oldSectionLocaleRecords = SectionLocaleRecord::model()->findAllByAttributes(array('sectionId' => $section->id));
                 $oldSectionLocales = SectionLocaleModel::populateModels($oldSectionLocaleRecords, 'locale');
             }
             foreach ($section->getLocales() as $localeId => $locale) {
                 $updateEntries = false;
                 // Was this already selected?
                 if (!$isNewSection && isset($oldSectionLocales[$localeId])) {
                     $oldLocale = $oldSectionLocales[$localeId];
                     // Has the URL format changed?
                     if ($locale->urlFormat != $oldLocale->urlFormat) {
                         craft()->db->createCommand()->update('sections_i18n', array('urlFormat' => $locale->urlFormat), array('id' => $oldLocale->id));
                         $updateEntries = true;
                     }
                 } else {
                     $newLocaleData[] = array($section->id, $localeId, $locale->urlFormat);
                     if (!$isNewSection) {
                         $updateEntries = true;
                     }
                 }
                 if ($updateEntries && $section->hasUrls) {
                     // This may take a while...
                     set_time_limit(120);
                     // Fetch all the entries in this section
                     $entries = craft()->elements->getCriteria(ElementType::Entry, array('sectionId' => $section->id, 'locale' => $localeId, 'limit' => null))->find();
                     foreach ($entries as $entry) {
                         $uri = craft()->templates->renderObjectTemplate($locale->urlFormat, $entry);
                         if ($uri != $entry->uri) {
                             craft()->db->createCommand()->update('elements_i18n', array('uri' => $uri), array('elementId' => $entry->id, 'locale' => $localeId));
                         }
                     }
                 }
             }
             // Insert the new locales
             craft()->db->createCommand()->insertAll('sections_i18n', array('sectionId', 'locale', 'urlFormat'), $newLocaleData);
             if (!$isNewSection) {
                 // Drop the old ones
                 $disabledLocaleIds = array_diff(array_keys($oldSectionLocales), array_keys($section->getLocales()));
                 foreach ($disabledLocaleIds as $localeId) {
                     craft()->db->createCommand()->delete('sections_i18n', array('id' => $oldSectionLocales[$localeId]->id));
                 }
                 // Drop the old entry URIs if the section no longer has URLs
                 if (!$section->hasUrls && $oldSection->hasUrls) {
                     // Clear out all the URIs
                     $entryIds = craft()->db->createCommand()->select('id')->from('entries')->where(array('sectionId' => $section->id))->queryColumn();
                     craft()->db->createCommand()->update('elements_i18n', array('uri' => null), array('in', 'elementId', $entryIds));
                 }
             }
             $transaction->commit();
         } catch (\Exception $e) {
             $transaction->rollBack();
             throw $e;
         }
         return true;
     } else {
         return false;
     }
 }