/** * Populates all of the native database fields and optionally fills in data relations. * Accepts an array of settings, ex: * * array( * 'only_empty' => true, // only fill in empty fields * 'include_relations' => true, // Include has_many and many_many relations * 'relation_create_limit' => 5, // If there aren't any existing records for many_many or has_one relations, limit creation to this number * 'download_images' => false, // Don't download images from the web. Use existing. * ); * * @param array $config The configuration options * @return DataObject */ public function fill($config = array()) { $faker = Faker\Factory::create(i18n::get_locale()); $defaults = Config::inst()->get("MockDataObject", "fill_options"); $create_limit = Config::inst()->get("MockDataObject", "relation_create_limit"); $settings = array_merge($defaults, $config); // Anything that is a core SiteTree field, e.g. "URLSegment", "ShowInMenus", "ParentID", we don't care about. $omit = Injector::inst()->get("SiteTree")->db(); // Except these two. unset($omit['Title']); unset($omit['Content']); $db = $this->owner->db(); foreach ($db as $fieldName => $fieldType) { if (in_array($fieldName, $omit)) { continue; } if ($settings['only_empty'] && $this->owner->obj($fieldName)->exists()) { continue; } $value = $this->owner->obj($fieldName)->getFakeData($faker); $this->owner->setField($fieldName, $value); } foreach ($this->owner->has_one() as $relation => $className) { $idField = $relation . "ID"; $sitetree = $className == "SiteTree" || is_subclass_of($className, "SiteTree"); if ($sitetree && $relation == "Parent") { continue; } $create_limit = Config::inst()->get("MockDataObject", "relation_create_limit"); if ($className == "File" || is_subclass_of($className, "File")) { if ($settings['only_empty'] && $this->owner->{$relation}()->exists()) { continue; } if ($settings['download_images']) { if ($image = self::download_lorem_image()) { $this->owner->{$idField} = $image->ID; } } else { if ($random_file = self::get_random_local_image()) { $this->owner->{$idField} = $random_file->ID; } } } else { if ($className == "Subsite") { continue; } else { $random_record = DataList::create($className)->sort("RAND()")->first(); if (!$random_record && !$sitetree) { $i = 0; while ($i <= $create_limit) { $r = new $className(); $r->fill($settings); $r->write(); $random_record = $r; $i++; } } $this->owner->{$idField} = $random_record->ID; } } } $this->owner->write(); if ($settings['include_relations']) { $SNG = Injector::inst()->get("SiteTree"); $skip = array_merge(array_keys($SNG->has_many()), array_keys($SNG->many_many())); foreach ($this->owner->has_many() as $relation => $className) { if (in_array($relation, $skip)) { continue; } $idField = Injector::inst()->get($className)->getReverseAssociation($this->owner->class); if (!$idField) { continue; } $idField .= "ID"; $count = rand(1, 10); $i = 0; while ($i <= $count) { $r = new $className(); $r->fill($settings); $r->{$idField} = $this->owner->ID; $r->write(); $i++; } } foreach ($this->owner->many_many() as $relation => $className) { if (in_array($relation, $skip)) { continue; } $records = DataList::create($className)->limit($create_limit); $diff = $records->count() - $create_limit; while ($diff < 0) { $r = new $className(); $r->fill($settings); $r->write(); $diff++; } $random_records = DataList::create($className)->sort("RAND()")->limit(rand(0, $create_limit)); $this->owner->{$relation}()->setByIDList($random_records->column('ID')); } } // Create a record of this mock data so that we can delete it later $log = MockDataLog::create(); $log->RecordClass = $this->owner->ClassName; $log->RecordID = $this->owner->ID; $log->write(); return $this->owner; }