/** * 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; } }