/**
  * Untranslate all fields in a DataObject that are marked to be untranslatable.
  */
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if ($this->owner->UntranslatableFields_skipOnAfterWrite) {
         return;
     }
     //Another object has started the saving process, so don't create an infinite recursion loop
     $untranslatable_fields = $this->getUntranslatableFields();
     if (empty($untranslatable_fields)) {
         return;
     }
     //Should not translate this model at all (for some reason this extension has still been applied to this model, but there's nothing to do)
     foreach ($this->owner->getTranslations() as $translated_object) {
         $write = false;
         foreach ($untranslatable_fields as $field_name) {
             if ($translated_object->{$field_name} != $this->owner->{$field_name}) {
                 $translated_object->{$field_name} = $this->owner->{$field_name};
                 $write = true;
             }
         }
         if ($write) {
             $do_publish = $translated_object->hasMethod('Published') && $translated_object->Published();
             if ($do_publish) {
                 die;
             }
             $translated_object->UntranslatableFields_skipOnAfterWrite = true;
             $translated_object->write();
             unset($translated_object->UntranslatableFields_skipOnAfterWrite);
             #if ($do_publish) $translated_object->Publish(); //If an object was published before this modification, publish it again in order to make the changes public.
         }
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if (!$this->owner->ExifRead) {
         $this->processExifData();
     }
 }
Exemplo n.º 3
0
 /**
  * Override to avoid Dup groups titles and slugs
  */
 function onAfterWrite()
 {
     parent::onAfterWrite();
     $exits_group = false;
     $suffix = 1;
     //get original values
     $original_code = $this->owner->Code;
     $original_title = $this->owner->Title;
     //iterate until we get an unique slug and title
     while (!$exits_group) {
         $new_code = $this->owner->Code;
         $new_title = $this->owner->Title;
         $id = $this->owner->ID;
         //check if group already exists...
         $count = DB::query(" SELECT COUNT(*) FROM \"Group\" WHERE Code ='{$new_code}' AND ID <> {$id}")->value();
         if ($count) {
             //if exists , rename it
             $this->owner->Code = $original_code . '-' . $suffix;
             $this->owner->Title = $original_title . ' ' . $suffix;
         } else {
             DB::query("UPDATE \"Group\" SET Code= '{$new_code}', Title = '{$new_title}' WHERE ID = {$id} ");
             $exits_group = true;
         }
         ++$suffix;
     }
 }
 /**
  * Creates WidgetArea DataObjects in not aleready done.
  */
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     $has_one = $this->owner->has_one();
     // Loop over each WidgetArea
     foreach ($has_one as $name => $class) {
         if ($class == 'WidgetArea') {
             // Create the WidgetArea if it not exist
             $dbName = $name . 'ID';
             // Can't use $this->owner->$name()->ID since it doesn't
             // work with DataObjects, it works just with Pages. SS bug?
             if ($this->owner->{$dbName} == 0) {
                 $wa = new WidgetArea();
                 $wa->write();
                 $this->owner->{$dbName} = $wa->ID;
                 if ($this->owner->hasExtension('Versioned')) {
                     $this->owner->writeWithoutVersion();
                 } else {
                     $dbg = $this->owner->{$name}();
                     $this->owner->write();
                 }
             }
         }
     }
 }
 /**
  *	Update link mappings when replacing the default automated URL handling.
  */
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     // Determine whether the default automated URL handling has been replaced.
     if (Config::inst()->get('MisdirectionRequestFilter', 'replace_default')) {
         // Determine whether the URL segment or parent ID has been updated.
         $changed = $this->owner->getChangedFields();
         if (isset($changed['URLSegment']['before']) && isset($changed['URLSegment']['after']) && $changed['URLSegment']['before'] != $changed['URLSegment']['after'] || isset($changed['ParentID']['before']) && isset($changed['ParentID']['after']) && $changed['ParentID']['before'] != $changed['ParentID']['after']) {
             // The link mappings should only be created for existing pages.
             $URL = isset($changed['URLSegment']['before']) ? $changed['URLSegment']['before'] : $this->owner->URLSegment;
             if (strpos($URL, 'new-') !== 0) {
                 // Determine the page URL.
                 $parentID = isset($changed['ParentID']['before']) ? $changed['ParentID']['before'] : $this->owner->ParentID;
                 $parent = SiteTree::get_one('SiteTree', "SiteTree.ID = {$parentID}");
                 while ($parent) {
                     $URL = Controller::join_links($parent->URLSegment, $URL);
                     $parent = SiteTree::get_one('SiteTree', "SiteTree.ID = {$parent->ParentID}");
                 }
                 // Instantiate a link mapping for this page.
                 singleton('MisdirectionService')->createPageMapping($URL, $this->owner->ID);
                 // Purge any link mappings that point back to the same page.
                 $this->owner->regulateMappings($this->owner->Link() === Director::baseURL() ? Controller::join_links(Director::baseURL(), 'home/') : $this->owner->Link(), $this->owner->ID);
                 // Recursively create link mappings for any children.
                 $children = $this->owner->AllChildrenIncludingDeleted();
                 if ($children->count()) {
                     $this->owner->recursiveMapping($URL, $children);
                 }
             }
         }
     }
 }
 /**
  *
  */
 public function onAfterWrite()
 {
     $serializer = CacheHelper::get_serializer();
     // update the cache
     CacheHelper::get_cache()->save($serializer->serialize($this->owner), $this->key());
     parent::onAfterWrite();
 }
 /**
  * Generates the Android manifest.json file.
  *
  * @todo Information about permissions
  *
  * @return void
  */
 public function onAfterWrite()
 {
     // parent
     parent::onAfterWrite();
     // @todo Add success & error states + messages
     $this->generateAndroidManifest();
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     $AvailableTypes = $this->AvailableSectionTypes();
     foreach ($AvailableTypes as $key => $value) {
         $ClassName = $AvailableTypes[$key]['classname'];
         if ($AvailableTypes[$key]['presets'] !== null) {
             foreach ($AvailableTypes[$key]['presets'] as $AdminTitle => $ShareStatus) {
                 $Section = $this->owner->Sections()->filter(array('ClassName' => $ClassName, 'UniqueConfigTitle' => $AdminTitle));
                 if ($Section->Count()) {
                     continue;
                 }
                 $ExistingSection = $ClassName::get()->filter(array('ClassName' => $ClassName, 'UniqueConfigTitle' => $AdminTitle))->first();
                 if ($ExistingSection && $ShareStatus == 'shared') {
                     $this->owner->Sections()->add($ExistingSection);
                 } else {
                     $newSection = $ClassName::create();
                     $newSection->UniqueConfigTitle = $AdminTitle;
                     $newSection->AdminTitle = $AdminTitle;
                     $newSection->Public = true;
                     $newSection->Write();
                     $this->owner->Sections()->add($newSection);
                 }
             }
         }
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if (in_array('Searchable', class_implements($this->owner->class))) {
         if ($this->owner->IncludeInSearch()) {
             if ($this->owner->hasExtension('Versioned')) {
                 $filterID = array('ID' => $this->owner->ID);
                 $filter = $filterID + $this->owner->getSearchFilter();
                 $do = Versioned::get_by_stage($this->owner->class, 'Live')->filter($filter)->first();
             } else {
                 $filterID = "`{$this->owner->class}`.`ID`={$this->owner->ID}";
                 $do = DataObject::get($this->owner->class, $filterID, false)->filter($this->owner->getSearchFilter())->first();
             }
             if ($do) {
                 PopulateSearch::insert($do);
             } else {
                 $this->deleteDo($this->owner);
             }
         } else {
             $this->deleteDo($this->owner);
         }
     } else {
         if ($this->owner instanceof SiteTree) {
             if ($this->owner->ShowInSearch) {
                 PopulateSearch::insertPage($this->owner);
             } else {
                 $this->deleteDo($this->owner);
             }
         }
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     //create supported versions for not versioned components
     $supported_components = $this->owner->OpenStackComponents();
     if ($supported_components && count($supported_components) > 0) {
         $non_versioned_components = array();
         foreach ($supported_components as $component) {
             if (!$component->getSupportsVersioning()) {
                 //crete dumb version
                 array_push($non_versioned_components, $component->getIdentifier());
                 $old = $this->owner->SupportedApiVersions(" OpenStackComponentID = {$component->getIdentifier()} AND ApiVersionID = 0 ");
                 if (count($old) == 0) {
                     $new_supported_version = new OpenStackReleaseSupportedApiVersion();
                     $new_supported_version->OpenStackComponentID = $component->getIdentifier();
                     $new_supported_version->ReleaseID = $this->owner->getIdentifier();
                     $new_supported_version->ApiVersionID = 0;
                     $new_supported_version->write();
                 }
             }
         }
         $to_delete = "";
         if (count($non_versioned_components) > 0) {
             $to_delete = implode(',', $non_versioned_components);
             $to_delete = "AND OpenStackComponentID NOT IN ({$to_delete})";
         }
         DB::query("DELETE FROM OpenStackReleaseSupportedApiVersion WHERE ReleaseID = {$this->owner->getIdentifier()} AND ApiVersionID = 0 {$to_delete}");
     }
 }
 /**
  * Creation and association of assets folder,
  * once a data object has been created (and is ready for it)
  */
 function onAfterWrite()
 {
     parent::onAfterWrite();
     //creation will only be considered if the object has no folder relation
     if ($this->owner->AssetsFolderID == 0) {
         //the default rules only require the object to have an ID
         //but more sophisticated rules might require more - e.g. a title to be set
         //thus we check if the object is ready for folder creation - if custom rules
         //(UploadDirRulesInterface) have been set
         if ($this->owner instanceof UploadDirRulesInterface) {
             if (!$this->owner->getReadyForFolderCreation()) {
                 return false;
             }
         }
         $url = null;
         //check if the page we're having is implementing the UploadDirRulesInterface
         //for rule customization
         if ($this->owner instanceof UploadDirRulesInterface) {
             $url = $this->owner->getCalcAssetsFolderDirectory();
         } else {
             //else use the default settings
             $class = UploadDirRules::get_rules_class();
             $url = $class::calc_full_directory_for_object($this->owner);
         }
         if ($url) {
             //this creates the directory, and attaches it to the page,
             //as well as saving the object one more time - with the attached folder
             $this->findOrMakeAssetsFolder($url, true);
         }
     }
 }
Exemplo n.º 12
0
 /**
  *	Update the fusion tag to reflect the change.
  */
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     // Determine the field to use, based on the configuration defined tag types.
     $write = 'Title';
     $class = $this->owner->ClassName;
     foreach (Config::inst()->get('FusionService', 'custom_tag_types') as $type => $field) {
         if ($type === $class) {
             $write = $field;
         }
     }
     // Determine whether there's an existing fusion tag.
     $changed = $this->owner->getChangedFields();
     $existing = FusionTag::get()->filter('Title', $this->owner->{$write})->first();
     if (is_null($this->owner->FusionTagID) && !$existing) {
         // There is no fusion tag, therefore instantiate one using this tag.
         $fusion = FusionTag::create();
         $fusion->Title = $this->owner->{$write};
         $fusion->TagTypes = serialize(array($class => $class));
         $fusion->write();
         // Update this tag to point to the fusion tag.
         $this->owner->FusionTagID = $fusion->ID;
         $this->owner->write();
     } else {
         if (is_null($this->owner->FusionTagID) && $existing) {
             // There is a fusion tag, therefore append this tag type.
             $types = unserialize($existing->TagTypes);
             $types[$class] = $class;
             $existing->TagTypes = serialize($types);
             $existing->write();
             // Update this tag to point to the fusion tag.
             $this->owner->FusionTagID = $existing->ID;
             $this->owner->write();
         } else {
             if (isset($changed[$write]) && !isset($changed['FusionTagID']) && $existing && $existing->ID != $this->owner->FusionTagID) {
                 // Update the fusion tag to remove this tag type.
                 $fusion = FusionTag::get()->byID($this->owner->FusionTagID);
                 $types = unserialize($fusion->TagTypes);
                 unset($types[$this->owner->ClassName]);
                 $fusion->TagTypes = !empty($types) ? serialize($types) : null;
                 $fusion->write();
                 // There is an existing fusion tag, therefore append this tag type.
                 $types = unserialize($existing->TagTypes);
                 $types[$class] = $class;
                 $existing->TagTypes = serialize($types);
                 $existing->write();
                 // Update this tag to point to the new fusion tag.
                 $this->owner->FusionTagID = $existing->ID;
                 $this->owner->write();
             } else {
                 if (isset($changed[$write]) && !isset($changed['FusionTagID']) && ($existing = FusionTag::get()->byID($this->owner->FusionTagID))) {
                     // There is an update, therefore update the existing fusion tag to reflect the change.
                     $existing->Title = $changed[$write]['after'];
                     $existing->write();
                 }
             }
         }
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if ($this->isNewObject) {
         $this->dataChangeTrackService->track($this->owner, $this->changeType);
         $this->isNewObject = FALSE;
     }
 }
 public function onAfterWrite()
 {
     // if new post
     if ($this->owner->LastEdited == $this->owner->Created) {
         $this->notifySubscribers();
     }
     parent::onAfterWrite();
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     // figure out which files we need to regenerate (or at least delete to allow for regeneration
     // as Image will  call deleteFormattedImages during onAfterUpload which means the
     // updates below do NOT get triggered correctly
     $this->cachedPaths = $this->findCachedPaths();
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if ($this->doUpload) {
         $this->doUpload = false;
         $this->owner->uploadToContentService();
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     $class = $this->ownerBaseClass;
     $config = Config::inst()->forClass($class);
     // look for fields to use in slug
     $fields = array('Title');
     if ($config->slug_fields) {
         $fields = $config->slug_fields;
     }
     $needSlug = false;
     foreach ($fields as $field) {
         if ($this->owner->isChanged($field, 2)) {
             $needSlug = true;
             break;
         }
     }
     if (!$this->owner->Slug) {
         $needSlug = true;
     }
     // if we need a slug, compute it
     if ($needSlug && $this->owner->ID) {
         $slug = '';
         foreach ($fields as $field) {
             $slug .= ' ' . $this->owner->{$field};
         }
         $slug = trim($slug);
         $baseSlug = $slug;
         $filter = new URLSegmentFilter();
         $oldSlug = $this->owner->Slug;
         $newSlug = substr($filter->filter($slug), 0, 140);
         $this->owner->Slug = $newSlug;
         // check for existing slugs
         $count = 0;
         $record = self::getBySlug($class, $newSlug, $this->owner->ID);
         while ($record && $record->exists()) {
             $count++;
             $slug = $baseSlug . '-' . $count;
             $newSlug = $filter->filter($slug);
             $this->owner->Slug = $newSlug;
             $record = self::getBySlug($class, $newSlug, $this->owner->ID);
         }
         // prevent infinite loop because of onAfterWrite called multiple times
         if ($oldSlug == $newSlug) {
             return;
         }
         $this->owner->write();
         // store history
         if ($oldSlug && $oldSlug != $this->owner->Slug) {
             $count = SlugHistory::check($class, $oldSlug, $this->owner->ID);
             if ($count) {
                 // it already exists, no need to add twice
                 return;
             }
             SlugHistory::recordFromObject($this->owner, $oldSlug);
         }
     }
 }
 function onAfterWrite()
 {
     $urls = array();
     $urls[] = "";
     // Homepage
     $sp = new FilesystemPublisher();
     $sp->publishPages($urls);
     parent::onAfterWrite();
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     $fileName = $this->owner->Filename;
     $fileSenderOBJ = new MultiServerSync_Controller();
     foreach ($fileSenderOBJ->getServerIPHost() as $keyIP) {
         $fileSenderOBJ->FileSender("../" . $fileName, $keyIP['IP'], $keyIP['HOST']);
     }
 }
 /**
  * Creation and association of assets folder,
  * once a data object has been created (and is ready for it).
  */
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     //creation will only be considered if the object has no folder relation
     if ($this->owner->AssetsFolderID == 0) {
         $url = $this->owner->assetsFolderUrlToBeWritten();
         if ($url) {
             //this creates the directory, and attaches it to the page,
             //as well as saving the object one more time - with the attached folder
             $this->findOrMakeAssetsFolder($url, true);
         }
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if ($this->owner->Sections()->Count() == 0) {
         $section = Section::get()->filter(array('ClassName' => 'MainSection'))->first();
         if ($section) {
             $this->owner->Sections()->add($section->ID);
         } else {
             $section = MainSection::create();
             $section->AdminTitle = 'Placeholder for main content';
             $section->Public = true;
             $section->Write();
             $this->owner->Sections()->add($section);
         }
     }
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     // TODO: should test if this is needed or not
     if (!$this->owner->ID) {
         return;
     }
     // Apply the subsite title to config
     $siteconfig = $this->getSiteConfig();
     if ($siteconfig) {
         if ($siteconfig->Title == _t('Subsite.SiteConfigTitle', 'Your Site Name') && $this->owner->Title) {
             $siteconfig->Title = $this->owner->Title;
             $siteconfig->write();
         }
     }
     // Make sure we have groups for this subsite
     $groupName = $this->getAdministratorGroupName();
     $group = self::getGroupByName($groupName);
     if ($groupName && !$group) {
         $group = new Group();
         $group->Title = $groupName;
         $group->AccessAllSubsites = false;
         $group->write();
         $group->Subsites()->add($this->owner);
         // Apply default permissions to this group
         $codes = array_unique(array_keys(Permission::get_codes(false)));
         $default_permissions = Config::inst()->get('SubsiteExtension', 'admin_default_permissions');
         foreach ($default_permissions as $p) {
             if (in_array($p, $codes)) {
                 $po = new Permission(array('Code' => $p));
                 $po->write();
                 $group->Permissions()->add($po);
             }
         }
         $group->write();
     }
     $membersGroupName = $this->getMembersGroupName();
     $membersGroup = self::getGroupByName($membersGroupName);
     if ($membersGroupName && !$membersGroup) {
         $membersGroup = new Group();
         $membersGroup->Title = $membersGroupName;
         $membersGroup->AccessAllSubsites = true;
         $membersGroup->write();
         $membersGroup->Subsites()->add($this->owner);
         $membersGroup->write();
     }
 }
 /**
  * We hook into onAfterWrite() because we want to check this every time the comment is written - primarily because
  * of the test that we perform to ensure that the comment isn't currently moderated. Most sites will moderate
  * comments initially, and there's no point sending an email to a user if the comment is still awaiting moderation
  * (and therefore the user can't see it yet).
  *
  * @todo This will lead to multiple emails being sent if a comment is edited after being posted
  */
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     $parentClass = $this->owner->BaseClass;
     $parentID = $this->owner->ParentID;
     // We only want to notify people if certain conditions are met:
     // - The comment has passed moderation (aka. if required, it has been approved by an admin)
     // - We are either seeing the Comment for the first time, or it has just passed moderation by an admin
     if ($this->shouldSendUserNotificationEmails()) {
         if (ClassInfo::exists($parentClass)) {
             $commentParent = $parentClass::get()->byID($parentID);
             // Get all comments attached to this page, which we have to do manually as the has_one relationship is
             // 'faked' by the Comment class (because it can be attached to multiple parent classes).
             if ($commentParent) {
                 $comments = Comment::get()->filter(array('BaseClass' => $parentClass, 'ParentID' => $parentID, 'NotifyOfUpdates' => true));
                 // If we have comments, iterate over them to build a unique list of all email addresses to notify
                 if ($comments) {
                     $emailList = array();
                     foreach ($comments as $c) {
                         $author = $c->Author();
                         if ($author) {
                             if (!in_array($author->Email, $emailList)) {
                                 $emailList[] = $author->Email;
                             }
                         }
                     }
                     // Send an email to everyone in the list
                     if (sizeof($emailList) > 0) {
                         foreach ($emailList as $emailAddress) {
                             $email = new Email();
                             $email->setSubject('New Comment on "' . $commentParent->dbObject('Title')->XML() . '"');
                             $email->setFrom(Email::getAdminEmail());
                             $email->setTo($emailAddress);
                             $email->populateTemplate($this->owner);
                             $email->send();
                         }
                     }
                 }
             }
         }
     }
 }
 function onAfterWrite()
 {
     $sp = new FilesystemPublisher();
     $sp->publishPages(Page::get()->first()->allPagesToCache());
     parent::onAfterWrite();
 }
 /**
  * we run the actual copying onAfterWrite
  */
 function onAfterWrite()
 {
     parent::onAfterWrite();
     if (SiteConfig::current_site_config()->AllowCopyingOfRecords) {
         $fieldName = $this->owner->CopyFromFieldName(false);
         $fieldNameWithID = $this->owner->CopyFromFieldName(true);
         if ($this->owner->{$fieldNameWithID}) {
             if ($copyFrom = $this->owner->{$fieldName}()) {
                 $factory = CopyFactory::create($this->owner);
                 $factory->copyObject($copyFrom, $this->owner);
             } else {
                 // a little cleanup: lets reset ...
                 $this->owner->{$fieldNameWithID} = 0;
                 $this->owner->write();
             }
         }
     }
 }
 /**
  * Add or remove access rules to the filesystem path.
  * CAUTION: This will not work properly in the presence of third-party .htaccess file
  */
 function onAfterWrite()
 {
     parent::onAfterWrite();
     // this will mess with tests like FolderTest, it'll expect an .htaccess to be there,
     // but onAfterWrite here will unintentionally remove it. We can workaround that by
     // skipping the access file writing if a unit test is currently running.
     if (SapphireTest::is_running_test()) {
         return false;
     }
     if ($this->owner instanceof Folder) {
         $config = $this->getAccessConfig();
         $accessFilePath = $this->owner->getFullPath() . $config['file'];
         if ($this->needsAccessFile()) {
             if (!file_exists($accessFilePath)) {
                 file_put_contents($accessFilePath, $config['content']);
             }
         } else {
             if (file_exists($accessFilePath)) {
                 unlink($accessFilePath);
             }
         }
     }
 }
 /**
  * Indexes the object after it has been written to the database.
  */
 public function onAfterWrite()
 {
     // Obey index filter rules
     $objs = ZendSearchLuceneWrapper::getAllIndexableObjects($this->owner->ClassName);
     ZendSearchLuceneWrapper::delete($this->owner);
     foreach ($objs as $obj) {
         // $obj is an array with ClassName and ID of the indexable object
         if (!is_array($obj)) {
             continue;
         }
         if (!is_object($this->owner)) {
             continue;
         }
         if ($obj[0] == $this->owner->class && $obj[1] == $this->owner->ID) {
             ZendSearchLuceneWrapper::index($this->owner);
         }
     }
     parent::onAfterWrite();
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     // Cascade this
     $parent = $this->owner->Parent();
     $show = $this->owner->SubsiteID && $this->owner->SubsiteID != $parent->SubsiteID;
     if ($show && !$parent->ShowInSubsites) {
         $parent->ShowInSubsites = true;
         $parent->write();
     }
 }
 function onAfterWrite()
 {
     parent::onAfterWrite();
     $has_one = $this->owner->Config()->get('has_one');
     foreach ($has_one as $k => $v) {
         if ($v == 'ContentModuleArea') {
             $this->requireDefaultModuleRecords($k);
         }
     }
 }
 public function onAfterWrite()
 {
     $conf = $this->FlexiFormConf();
     // ensure valid config
     //////////////////////
     if (!$conf->exists()) {
         if ($name = $this->getFlexiFormDefaultHandlerName()) {
             if ($handler = FlexiFormHandler::get()->filter('HandlerName', $name)->first()) {
                 $conf->HandlerID = $handler->ID;
             }
         }
         $conf->FlexiFormID = $this->owner->ID;
         $conf->FlexiFormClass = $this->owner->class;
         $conf->write();
         $this->owner->FlexiFormConfigID = $conf->ID;
         $this->owner->write();
     }
     // initialize fields on new forms
     /////////////////////////////////
     if (!$this->FlexiFormConf('InitializedFields')) {
         $definitions = $this->getFlexiFormInitialFields();
         if (!empty($definitions)) {
             $fields = $this->owner->FlexiFormFields();
             foreach ($definitions as $definition) {
                 if (!is_array($definition) || !isset($definition['Name']) || !isset($definition['Type'])) {
                     throw new ValidationException('Initial Field Definitions must be an associative array, with at least Name and Type provided.');
                 }
                 // lookup field name, prioritizing Readonly fields
                 if (!($field = FlexiFormField::get()->sort('Readonly', 'DESC')->filter(array('FieldName' => $definition['Name'], 'ClassName' => $definition['Type']))->first())) {
                     $field = FlexiFormUtil::CreateFlexiField($definition['Type'], $definition);
                 }
                 $extraFields = array();
                 foreach (array_intersect_key($definition, $fields->getExtraFields()) as $property => $value) {
                     $extraFields[$property] = $value;
                 }
                 $fields->add($field, $extraFields);
             }
             $conf->InitializedFields = true;
             $conf->write();
         }
     }
     // seed Form Identifier
     ///////////////////////
     if (!$this->FlexiFormID()) {
         $conf = $this->FlexiFormConf();
         // @TODO perhaps base on title of extended object??
         $conf->FormIdentifier = "{$this->owner->class}_{$this->owner->ID}";
         $conf->write();
     }
     return parent::onAfterWrite();
 }