/** * Handle the onBeforeSaveEntry event. * * @param Event $event */ public function onBeforeSaveEntry(Event $event) { // Get entry id to save $id = $event->params['entry']->id; if (!$event->params['isNewEntry']) { // Get old entry from db $entry = EntryModel::populateModel(EntryRecord::model()->findById($id)); // Get fields $this->before = $this->fields($entry); } else { // Get fields $this->before = $this->fields($event->params['entry'], true); } }
/** * Saves an entry. * * @param EntryModel $entry * @throws Exception * @return bool */ public function saveEntry(EntryModel $entry) { $isNewEntry = !$entry->id; // Entry data if (!$isNewEntry) { $entryRecord = EntryRecord::model()->with('element')->findById($entry->id); if (!$entryRecord) { throw new Exception(Craft::t('No entry exists with the ID “{id}”', array('id' => $entry->id))); } $elementRecord = $entryRecord->element; // if entry->sectionId is null and there is an entryRecord sectionId, we assume this is a front-end edit. if ($entry->sectionId === null && $entryRecord->sectionId) { $entry->sectionId = $entryRecord->sectionId; } } else { $entryRecord = new EntryRecord(); $elementRecord = new ElementRecord(); $elementRecord->type = ElementType::Entry; } $section = craft()->sections->getSectionById($entry->sectionId); if (!$section) { throw new Exception(Craft::t('No section exists with the ID “{id}”', array('id' => $entry->sectionId))); } $sectionLocales = $section->getLocales(); if (!isset($sectionLocales[$entry->locale])) { throw new Exception(Craft::t('The section “{section}” is not enabled for the locale {locale}', array('section' => $section->name, 'locale' => $entry->locale))); } $entryRecord->sectionId = $entry->sectionId; $entryRecord->authorId = $entry->authorId; $entryRecord->postDate = $entry->postDate; $entryRecord->expiryDate = $entry->expiryDate; if ($entry->enabled && !$entryRecord->postDate) { // Default the post date to the current date/time $entryRecord->postDate = $entry->postDate = DateTimeHelper::currentUTCDateTime(); } $entryRecord->validate(); $entry->addErrors($entryRecord->getErrors()); $elementRecord->enabled = $entry->enabled; $elementRecord->validate(); $entry->addErrors($elementRecord->getErrors()); // Entry locale data if ($entry->id) { $entryLocaleRecord = EntryLocaleRecord::model()->findByAttributes(array('entryId' => $entry->id, 'locale' => $entry->locale)); // If entry->slug is null and there is an entryLocaleRecord slug, we assume this is a front-end edit. if ($entry->slug === null && $entryLocaleRecord->slug) { $entry->slug = $entryLocaleRecord->slug; } } if (empty($entryLocaleRecord)) { $entryLocaleRecord = new EntryLocaleRecord(); $entryLocaleRecord->sectionId = $entry->sectionId; $entryLocaleRecord->locale = $entry->locale; } if ($entryLocaleRecord->isNewRecord() || $entry->slug != $entryLocaleRecord->slug) { $this->_generateEntrySlug($entry); $entryLocaleRecord->slug = $entry->slug; } $entryLocaleRecord->validate(); $entry->addErrors($entryLocaleRecord->getErrors()); // Element locale data if ($entry->id) { $elementLocaleRecord = ElementLocaleRecord::model()->findByAttributes(array('elementId' => $entry->id, 'locale' => $entry->locale)); } if (empty($elementLocaleRecord)) { $elementLocaleRecord = new ElementLocaleRecord(); $elementLocaleRecord->locale = $entry->locale; } if ($section->hasUrls && $entry->enabled) { // Make sure the section's URL format is valid. This shouldn't be possible due to section validation, // but it's not enforced by the DB, so anything is possible. $urlFormat = $sectionLocales[$entry->locale]->urlFormat; if (!$urlFormat || strpos($urlFormat, '{slug}') === false) { throw new Exception(Craft::t('The section “{section}” doesn’t have a valid URL Format.', array('section' => Craft::t($section->name)))); } $elementLocaleRecord->uri = craft()->templates->renderObjectTemplate($urlFormat, $entry); } else { $elementLocaleRecord->uri = null; } $elementLocaleRecord->validate(); $entry->addErrors($elementLocaleRecord->getErrors()); // Entry content $fieldLayout = $section->getFieldLayout(); $content = craft()->content->prepElementContentForSave($entry, $fieldLayout); $content->validate(); $entry->addErrors($content->getErrors()); if (!$entry->hasErrors()) { // Save the element record first $elementRecord->save(false); // Now that we have an element ID, save it on the other stuff if (!$entry->id) { $entry->id = $elementRecord->id; $entryRecord->id = $entry->id; } $entryRecord->save(false); $entryLocaleRecord->entryId = $entry->id; $elementLocaleRecord->elementId = $entry->id; $content->elementId = $entry->id; // Save the other records $entryLocaleRecord->save(false); $elementLocaleRecord->save(false); craft()->content->saveContent($content, false); // Update the search index craft()->search->indexElementAttributes($entry, $entry->locale); // Save a new version if (Craft::hasPackage(CraftPackage::PublishPro)) { craft()->entryRevisions->saveVersion($entry); } // Perform some post-save operations craft()->content->postSaveOperations($entry, $content); // Fire an 'onSaveEntry' event $this->onSaveEntry(new Event($this, array('entry' => $entry, 'isNewEntry' => $isNewEntry))); return true; } else { return false; } }
/** * Saves a new or existing entry. * * ```php * $entry = new EntryModel(); * $entry->sectionId = 10; * $entry->typeId = 1; * $entry->authorId = 5; * $entry->enabled = true; * * $entry->getContent()->title = "Hello World!"; * * $entry->setContentFromPost(array( * 'body' => "<p>I can’t believe I literally just called this “Hello World!”.</p>", * )); * * $success = craft()->entries->saveEntry($entry); * * if (!$success) * { * Craft::log('Couldn’t save the entry "'.$entry->title.'"', LogLevel::Error); * } * ``` * * @param EntryModel $entry The entry to be saved. * * @throws \Exception * @return bool Whether the entry was saved successfully. */ public function saveEntry(EntryModel $entry) { $isNewEntry = !$entry->id; $hasNewParent = $this->_checkForNewParent($entry); if ($hasNewParent) { if ($entry->parentId) { $parentEntry = $this->getEntryById($entry->parentId, $entry->locale); if (!$parentEntry) { throw new Exception(Craft::t('No entry exists with the ID “{id}”.', array('id' => $entry->parentId))); } } else { $parentEntry = null; } $entry->setParent($parentEntry); } // Get the entry record if (!$isNewEntry) { $entryRecord = EntryRecord::model()->findById($entry->id); if (!$entryRecord) { throw new Exception(Craft::t('No entry exists with the ID “{id}”.', array('id' => $entry->id))); } } else { $entryRecord = new EntryRecord(); } // Get the section $section = craft()->sections->getSectionById($entry->sectionId); if (!$section) { throw new Exception(Craft::t('No section exists with the ID “{id}”.', array('id' => $entry->sectionId))); } // Verify that the section is available in this locale $sectionLocales = $section->getLocales(); if (!isset($sectionLocales[$entry->locale])) { throw new Exception(Craft::t('The section “{section}” is not enabled for the locale {locale}', array('section' => $section->name, 'locale' => $entry->locale))); } // Set the entry data $entryType = $entry->getType(); $entryRecord->sectionId = $entry->sectionId; if ($section->type == SectionType::Single) { $entryRecord->authorId = $entry->authorId = null; $entryRecord->expiryDate = $entry->expiryDate = null; } else { $entryRecord->authorId = $entry->authorId; $entryRecord->postDate = $entry->postDate; $entryRecord->expiryDate = $entry->expiryDate; $entryRecord->typeId = $entryType->id; } if ($entry->enabled && !$entryRecord->postDate) { // Default the post date to the current date/time $entryRecord->postDate = $entry->postDate = DateTimeHelper::currentUTCDateTime(); } $entryRecord->validate(); $entry->addErrors($entryRecord->getErrors()); if ($entry->hasErrors()) { return false; } if (!$entryType->hasTitleField) { $entry->getContent()->title = craft()->templates->renderObjectTemplate($entryType->titleFormat, $entry); } $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { // Fire an 'onBeforeSaveEntry' event $event = new Event($this, array('entry' => $entry, 'isNewEntry' => $isNewEntry)); $this->onBeforeSaveEntry($event); // Is the event giving us the go-ahead? if ($event->performAction) { // Save the element $success = craft()->elements->saveElement($entry); // If it didn't work, rollback the transaction in case something changed in onBeforeSaveEntry if (!$success) { if ($transaction !== null) { $transaction->rollback(); } // If "title" has an error, check if they've defined a custom title label. if ($entry->getError('title')) { // Grab all of the original errors. $errors = $entry->getErrors(); // Grab just the title error message. $originalTitleError = $errors['title']; // Clear the old. $entry->clearErrors(); // Create the new "title" error message. $errors['title'] = str_replace('Title', $entryType->titleLabel, $originalTitleError); // Add all of the errors back on the model. $entry->addErrors($errors); } return false; } // Now that we have an element ID, save it on the other stuff if ($isNewEntry) { $entryRecord->id = $entry->id; } // Save the actual entry row $entryRecord->save(false); if ($section->type == SectionType::Structure) { // Has the parent changed? if ($hasNewParent) { if (!$entry->parentId) { craft()->structures->appendToRoot($section->structureId, $entry); } else { craft()->structures->append($section->structureId, $entry, $parentEntry); } } // Update the entry's descendants, who may be using this entry's URI in their own URIs craft()->elements->updateDescendantSlugsAndUris($entry); } // Save a new version if (craft()->getEdition() >= Craft::Client && $section->enableVersioning) { craft()->entryRevisions->saveVersion($entry); } } else { $success = false; } // Commit the transaction regardless of whether we saved the entry, in case something changed // in onBeforeSaveEntry if ($transaction !== null) { $transaction->commit(); } } catch (\Exception $e) { if ($transaction !== null) { $transaction->rollback(); } throw $e; } if ($success) { // Fire an 'onSaveEntry' event $this->onSaveEntry(new Event($this, array('entry' => $entry, 'isNewEntry' => $isNewEntry))); } return $success; }
/** * Initialize the category saving/deleting events. */ public function log() { // Get values before saving craft()->on('entries.onBeforeSaveEntry', function (Event $event) { // Get entry id to save $id = $event->params['entry']->id; if (!$event->params['isNewEntry']) { // Get old entry from db $entry = EntryModel::populateModel(EntryRecord::model()->findById($id)); // Get fields craft()->auditLog_entry->before = craft()->auditLog_entry->fields($entry); } else { // Get fields craft()->auditLog_entry->before = craft()->auditLog_entry->fields($event->params['entry'], true); } }); // Get values after saving craft()->on('entries.onSaveEntry', function (Event $event) { // Get saved entry $entry = $event->params['entry']; // Get fields craft()->auditLog_entry->after = craft()->auditLog_entry->fields($entry); // New row $log = new AuditLogRecord(); // Get user $user = craft()->userSession->getUser(); // Set user id $log->userId = $user ? $user->id : null; // Set element type $log->type = ElementType::Entry; // Set origin $log->origin = craft()->request->isCpRequest() ? craft()->config->get('cpTrigger') . '/' . craft()->request->path : craft()->request->path; // Set before $log->before = craft()->auditLog_entry->before; // Set after $log->after = craft()->auditLog_entry->after; // Set status $log->status = $event->params['isNewEntry'] ? AuditLogModel::CREATED : AuditLogModel::MODIFIED; // Save row $log->save(false); // Callback craft()->auditLog->elementHasChanged(ElementType::Entry, $entry->id, craft()->auditLog_entry->before, craft()->auditLog_entry->after); }); // Get values before deleting craft()->on('entries.onBeforeDeleteEntry', function (Event $event) { // Get deleted entry $entry = $event->params['entry']; // Get fields craft()->auditLog_entry->before = craft()->auditLog_entry->fields($entry); craft()->auditLog_entry->after = craft()->auditLog_entry->fields($entry, true); // New row $log = new AuditLogRecord(); // Set user id $log->userId = craft()->userSession->getUser()->id; // Set element type $log->type = ElementType::Entry; // Set origin $log->origin = craft()->request->isCpRequest() ? craft()->config->get('cpTrigger') . '/' . craft()->request->path : craft()->request->path; // Set before $log->before = craft()->auditLog_entry->before; // Set after $log->after = craft()->auditLog_entry->after; // Set status $log->status = AuditLogModel::DELETED; // Save row $log->save(false); // Callback craft()->auditLog->elementHasChanged(ElementType::Entry, $entry->id, craft()->auditLog_entry->before, craft()->auditLog_entry->after); }); }