public function Form() { $player = DataObject::get('GridFieldTest_Player')->find('Email', '*****@*****.**'); $config = GridFieldConfig::create()->addComponents($relationComponent = new GridFieldAddExistingAutocompleter('before'), new GridFieldDataColumns()); $field = new GridField('testfield', 'testfield', $player->Teams(), $config); return new Form($this, 'Form', new FieldList($field), new FieldList()); }
public function testCreateWithTransaction() { if (DB::get_conn()->supportsTransactions() == true) { DB::get_conn()->transactionStart(); $obj = new TransactionTest_Object(); $obj->Title = 'First page'; $obj->write(); $obj = new TransactionTest_Object(); $obj->Title = 'Second page'; $obj->write(); //Create a savepoint here: DB::get_conn()->transactionSavepoint('rollback'); $obj = new TransactionTest_Object(); $obj->Title = 'Third page'; $obj->write(); $obj = new TransactionTest_Object(); $obj->Title = 'Fourth page'; $obj->write(); //Revert to a savepoint: DB::get_conn()->transactionRollback('rollback'); DB::get_conn()->transactionEnd(); $first = DataObject::get('TransactionTest_Object', "\"Title\"='First page'"); $second = DataObject::get('TransactionTest_Object', "\"Title\"='Second page'"); $third = DataObject::get('TransactionTest_Object', "\"Title\"='Third page'"); $fourth = DataObject::get('TransactionTest_Object', "\"Title\"='Fourth page'"); //These pages should be in the system $this->assertTrue(is_object($first) && $first->exists()); $this->assertTrue(is_object($second) && $second->exists()); //These pages should NOT exist, we reverted to a savepoint: $this->assertFalse(is_object($third) && $third->exists()); $this->assertFalse(is_object($fourth) && $fourth->exists()); } else { $this->markTestSkipped('Current database does not support transactions'); } }
public function testDelete() { $role = $this->objFromFixture('SilverStripe\\Security\\PermissionRole', 'role'); $role->delete(); $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\PermissionRole', "\"ID\"={$role->ID}")->count(), 'Role is removed'); $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\PermissionRoleCode', "\"RoleID\"={$role->ID}")->count(), 'Permissions removed along with the role'); }
public function testArrayValueWithSqlMapSource() { $member1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member1'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member2'); $member3 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member3'); $source = DataObject::get('SilverStripe\\Security\\Member'); $f = new LookupField('test', 'test', $source->map('ID', 'FirstName')); $f->setValue(array($member1->ID, $member2->ID)); $this->assertEquals(sprintf('<span class="readonly" id="test">member1, member2</span>' . '<input type="hidden" name="test" value="%s, %s" />', $member1->ID, $member2->ID), trim($f->Field()->getValue())); }
public function testLoadDataFromObject() { $article = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags'); $articleWithTags = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithtags'); $tag1 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1'); $tag2 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2'); $field = new CheckboxSetField("Tags", "Test field", DataObject::get("CheckboxSetFieldTest_Tag")->map()); $form = new Form(new Controller(), 'Form', new FieldList($field), new FieldList()); $form->loadDataFrom($articleWithTags); $value = $field->Value(); sort($value); $this->assertEquals(array($tag1->ID, $tag2->ID), $value, 'CheckboxSetField loads data from a manymany relationship in an object through Form->loadDataFrom()'); }
/** * Test plain import with clear_table_before_import */ public function testDeleteExistingRecords() { $loader = new CsvBulkLoader('CsvBulkLoaderTest_Player'); $filepath = $this->getCurrentAbsolutePath() . '/CsvBulkLoaderTest_PlayersWithHeader.csv'; $loader->deleteExistingRecords = true; $results1 = $loader->load($filepath); $this->assertEquals(4, $results1->Count(), 'Test correct count of imported data on first load'); //delete existing data before doing second CSV import $results2 = $loader->load($filepath, '512MB', true); //get all instances of the loaded DataObject from the database and count them $resultDataObject = DataObject::get('CsvBulkLoaderTest_Player'); $this->assertEquals(4, $resultDataObject->Count(), 'Test if existing data is deleted before new data is added'); }
public function setUp() { parent::setUp(); Versioned::set_stage(Versioned::DRAFT); // Automatically publish any object named *_published foreach ($this->getFixtureFactory()->getFixtures() as $class => $fixtures) { foreach ($fixtures as $name => $id) { if (stripos($name, '_published') !== false) { /** @var Versioned|DataObject $object */ $object = DataObject::get($class)->byID($id); $object->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); } } } }
/** * Ensure that changes to records flush overwritten files, and update the visibility * of other assets. */ public function onBeforeWrite() { // Prepare blank manipulation $manipulations = new AssetManipulationList(); // Mark overwritten object as deleted if ($this->owner->isInDB()) { $priorRecord = DataObject::get(get_class($this->owner))->byID($this->owner->ID); if ($priorRecord) { $this->addAssetsFromRecord($manipulations, $priorRecord, AssetManipulationList::STATE_DELETED); } } // Add assets from new record with the correct visibility rules $state = $this->getRecordState($this->owner); $this->addAssetsFromRecord($manipulations, $this->owner, $state); // Whitelist assets that exist in other stages $this->addAssetsFromOtherStages($manipulations); // Apply visibility rules based on the final manipulation $this->processManipulation($manipulations); }
/** * Test that you can call Hierarchy::markExpanded/Unexpanded/Open() on a obj, and that * calling Hierarchy::isMarked() on a different instance of that object will return true. */ public function testItemMarkingIsntRestrictedToSpecificInstance() { // Mark a few objs $this->objFromFixture('HierarchyTest_Object', 'obj2')->markExpanded(); $this->objFromFixture('HierarchyTest_Object', 'obj2a')->markExpanded(); $this->objFromFixture('HierarchyTest_Object', 'obj2b')->markExpanded(); $this->objFromFixture('HierarchyTest_Object', 'obj3')->markUnexpanded(); // Query some objs in a different context and check their m $objs = DataObject::get("HierarchyTest_Object", '', '"ID" ASC'); $marked = $expanded = array(); foreach ($objs as $obj) { if ($obj->isMarked()) { $marked[] = $obj->Title; } if ($obj->isExpanded()) { $expanded[] = $obj->Title; } } $this->assertEquals(array('Obj 2', 'Obj 3', 'Obj 2a', 'Obj 2b'), $marked); $this->assertEquals(array('Obj 2', 'Obj 2a', 'Obj 2b'), $expanded); }
public function testSaveInto() { $group = $this->objFromFixture('SilverStripe\\Security\\Group', 'group'); // tested group $untouchable = $this->objFromFixture('SilverStripe\\Security\\Group', 'untouchable'); // group that should not change $field = new PermissionCheckboxSetField('Permissions', 'Permissions', 'SilverStripe\\Security\\Permission', 'GroupID', $group); // get the number of permissions before we start $baseCount = DataObject::get('SilverStripe\\Security\\Permission')->Count(); // there are currently no permissions, save empty checkbox $field->saveInto($group); $group->flushCache(); $untouchable->flushCache(); $this->assertEquals($group->Permissions()->Count(), 0, 'The tested group has no permissions'); $this->assertEquals($untouchable->Permissions()->Count(), 1, 'The other group has one permission'); $this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, 'The other group has ADMIN permission'); $this->assertEquals(DataObject::get('SilverStripe\\Security\\Permission')->Count(), $baseCount, 'There are no orphaned permissions'); // add some permissions $field->setValue(array('ADMIN' => true, 'NON-ADMIN' => true)); $field->saveInto($group); $group->flushCache(); $untouchable->flushCache(); $this->assertEquals($group->Permissions()->Count(), 2, 'The tested group has two permissions permission'); $this->assertEquals($group->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, 'The tested group has ADMIN permission'); $this->assertEquals($group->Permissions()->where("\"Code\"='NON-ADMIN'")->Count(), 1, 'The tested group has CMS_ACCESS_AssetAdmin permission'); $this->assertEquals($untouchable->Permissions()->Count(), 1, 'The other group has one permission'); $this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, 'The other group has ADMIN permission'); $this->assertEquals(DataObject::get('SilverStripe\\Security\\Permission')->Count(), $baseCount + 2, 'There are no orphaned permissions'); // remove permission $field->setValue(array('ADMIN' => true)); $field->saveInto($group); $group->flushCache(); $untouchable->flushCache(); $this->assertEquals($group->Permissions()->Count(), 1, 'The tested group has 1 permission'); $this->assertEquals($group->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, 'The tested group has ADMIN permission'); $this->assertEquals($untouchable->Permissions()->Count(), 1, 'The other group has one permission'); $this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, 'The other group has ADMIN permission'); $this->assertEquals(DataObject::get('SilverStripe\\Security\\Permission')->Count(), $baseCount + 1, 'There are no orphaned permissions'); }
/** * Link this group set to a specific member. * * Recursively selects all groups applied to this member, as well as any * parent groups of any applied groups * * @param array|integer $id (optional) An ID or an array of IDs - if not provided, will use the current * ids as per getForeignID * @return array Condition In array(SQL => parameters format) */ public function foreignIDFilter($id = null) { if ($id === null) { $id = $this->getForeignID(); } // Find directly applied groups $manyManyFilter = parent::foreignIDFilter($id); $query = new SQLSelect('"Group_Members"."GroupID"', '"Group_Members"', $manyManyFilter); $groupIDs = $query->execute()->column(); // Get all ancestors, iteratively merging these into the master set $allGroupIDs = array(); while ($groupIDs) { $allGroupIDs = array_merge($allGroupIDs, $groupIDs); $groupIDs = DataObject::get("SilverStripe\\Security\\Group")->byIDs($groupIDs)->column("ParentID"); $groupIDs = array_filter($groupIDs); } // Add a filter to this DataList if (!empty($allGroupIDs)) { $allGroupIDsPlaceholders = DB::placeholders($allGroupIDs); return array("\"Group\".\"ID\" IN ({$allGroupIDsPlaceholders})" => $allGroupIDs); } else { return array('"Group"."ID"' => 0); } }
/** * Searches the SiteTree for display in the dropdown * * @return callback */ public function siteTreeSearchCallback($sourceObject, $labelField, $search) { return DataObject::get($sourceObject)->filterAny(array('MenuTitle:PartialMatch' => $search, 'Title:PartialMatch' => $search)); }
/** * Find an existing objects based on one or more uniqueness columns * specified via {@link self::$duplicateChecks}. * * @todo support $columnMap * * @param array $record CSV data column * @param array $columnMap * @return DataObject */ public function findExistingObject($record, $columnMap = []) { $SNG_objectClass = singleton($this->objectClass); // checking for existing records (only if not already found) foreach ($this->duplicateChecks as $fieldName => $duplicateCheck) { $existingRecord = null; if (is_string($duplicateCheck)) { // Skip current duplicate check if field value is empty if (empty($record[$duplicateCheck])) { continue; } // Check existing record with this value $dbFieldValue = $record[$duplicateCheck]; $existingRecord = DataObject::get($this->objectClass)->filter($duplicateCheck, $dbFieldValue)->first(); if ($existingRecord) { return $existingRecord; } } elseif (is_array($duplicateCheck) && isset($duplicateCheck['callback'])) { if ($this->hasMethod($duplicateCheck['callback'])) { $existingRecord = $this->{$duplicateCheck['callback']}($record[$fieldName], $record); } elseif ($SNG_objectClass->hasMethod($duplicateCheck['callback'])) { $existingRecord = $SNG_objectClass->{$duplicateCheck['callback']}($record[$fieldName], $record); } else { user_error("CsvBulkLoader::processRecord():" . " {$duplicateCheck['callback']} not found on importer or object class.", E_USER_ERROR); } if ($existingRecord) { return $existingRecord; } } else { user_error('CsvBulkLoader::processRecord(): Wrong format for $duplicateChecks', E_USER_ERROR); } } return false; }
/** * Allows requesting a view update on specific tree nodes. * Similar to {@link getsubtree()}, but doesn't enforce loading * all children with the node. Useful to refresh views after * state modifications, e.g. saving a form. * * @param HTTPRequest $request * @return string JSON */ public function updatetreenodes($request) { $data = array(); $ids = explode(',', $request->getVar('ids')); foreach ($ids as $id) { if ($id === "") { continue; } // $id may be a blank string, which is invalid and should be skipped over $record = $this->getRecord($id); if (!$record) { continue; } // In case a page is no longer available $recordController = $this->stat('tree_class') == 'SilverStripe\\CMS\\Model\\SiteTree' ? CMSPageEditController::singleton() : $this; // Find the next & previous nodes, for proper positioning (Sort isn't good enough - it's not a raw offset) // TODO: These methods should really be in hierarchy - for a start it assumes Sort exists $next = $prev = null; $className = $this->stat('tree_class'); $next = DataObject::get($className)->filter('ParentID', $record->ParentID)->filter('Sort:GreaterThan', $record->Sort)->first(); if (!$next) { $prev = DataObject::get($className)->filter('ParentID', $record->ParentID)->filter('Sort:LessThan', $record->Sort)->reverse()->first(); } $link = Controller::join_links($recordController->Link("show"), $record->ID); $html = LeftAndMain_TreeNode::create($record, $link, $this->isCurrentPage($record))->forTemplate() . '</li>'; $data[$id] = array('html' => $html, 'ParentID' => $record->ParentID, 'NextID' => $next ? $next->ID : null, 'PrevID' => $prev ? $prev->ID : null); } $this->getResponse()->addHeader('Content-Type', 'text/json'); return Convert::raw2json($data); }
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema * @param bool $testMode */ public function doBuild($quiet = false, $populate = true, $testMode = false) { if ($quiet) { DB::quiet(); } else { $conn = DB::get_conn(); // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database") $dbType = substr(get_class($conn), 0, -8); $dbVersion = $conn->getVersion(); $databaseName = method_exists($conn, 'currentDatabase') ? $conn->getSelectedDatabase() : ""; if (Director::is_cli()) { echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion); } else { echo sprintf("<h2>Building database %s using %s %s</h2>", $databaseName, $dbType, $dbVersion); } } // Set up the initial database if (!DB::is_active()) { if (!$quiet) { echo '<p><b>Creating database</b></p>'; } // Load parameters from existing configuration global $databaseConfig; if (empty($databaseConfig) && empty($_REQUEST['db'])) { user_error("No database configuration available", E_USER_ERROR); } $parameters = !empty($databaseConfig) ? $databaseConfig : $_REQUEST['db']; // Check database name is given if (empty($parameters['database'])) { user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR); } $database = $parameters['database']; // Establish connection and create database in two steps unset($parameters['database']); DB::connect($parameters); DB::create_database($database); } // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('SilverStripe\\ORM\\DataObject'); array_shift($dataClasses); if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE TABLES\n\n"; } else { echo "\n<p><b>Creating database tables</b></p>\n\n"; } } // Initiate schema update $dbSchema = DB::get_schema(); $dbSchema->schemaUpdate(function () use($dataClasses, $testMode, $quiet) { foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (!class_exists($dataClass)) { continue; } // Check if this class should be excluded as per testing conventions $SNG = singleton($dataClass); if (!$testMode && $SNG instanceof TestOnly) { continue; } // Log data if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } // Instruct the class to apply its schema to the database $SNG->requireTable(); } }); ClassInfo::reset_db_cache(); if ($populate) { if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE RECORDS\n\n"; } else { echo "\n<p><b>Creating database records</b></p>\n\n"; } } foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false && class_exists($dataClass)) { if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } singleton($dataClass)->requireDefaultRecords(); } } // Remap obsolete class names $schema = DataObject::getSchema(); foreach ($this->config()->classname_value_remapping as $oldClassName => $newClassName) { $baseDataClass = $schema->baseDataClass($newClassName); $badRecordCount = DataObject::get($baseDataClass)->filter(["ClassName" => $oldClassName])->count(); if ($badRecordCount > 0) { if (Director::is_cli()) { echo " * Correcting {$badRecordCount} obsolete classname values for {$newClassName}\n"; } else { echo "<li>Correcting {$badRecordCount} obsolete classname values for {$newClassName}</li>\n"; } $table = $schema->baseDataTable($baseDataClass); DB::prepared_query("UPDATE \"{$table}\" SET \"ClassName\" = ? WHERE \"ClassName\" = ?", [$newClassName, $oldClassName]); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if (isset($_REQUEST['from_installer'])) { echo "OK"; } if (!$quiet) { echo Director::is_cli() ? "\n Database build completed!\n\n" : "<p>Database build completed!</p>"; } ClassInfo::reset_db_cache(); }
public function testValidationWithDataList() { //test with datalist input $tag1 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag1'); $tag2 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag2'); $tag3 = $this->objFromFixture('ListboxFieldTest_Tag', 'tag3'); $field = ListboxField::create('Test', 'Testing', DataObject::get("ListboxFieldTest_Tag")->map()->toArray()); $validator = new RequiredFields(); $field->setValue($tag1->ID); $this->assertTrue($field->validate($validator), 'Field validates values in source map'); /** * @todo re-enable these tests when field validation is removed from {@link ListboxField::setValue()} and moved * to the {@link ListboxField::validate()} function */ // $field->setValue(4); // $this->assertFalse( // $field->validate($validator), // 'Field does not validate values outside of source map' // ); $field->setValue(false, new ArrayData(array($tag1->ID => $tag1->ID, $tag2->ID => $tag2->ID))); $this->assertTrue($field->validate($validator), 'Validates values in source map'); //invalid value should fail $field->setValue(4); $this->assertFalse($field->validate($validator), 'Does not validate values not within source map'); }
/** * Get the object where the $keyField is equal to a certain value * * @param string|int $key * @return DataObject */ protected function objectForKey($key) { return DataObject::get($this->sourceObject)->filter($this->keyField, $key)->first(); }
public function testLazyLoadedFieldsGetAllFields() { $subteam1 = $this->objFromFixture('DataObjectTest_SubTeam', 'subteam1'); $parentTeam = $this->objFromFixture('DataObjectTest_Team', 'team1'); $teams = DataObject::get('DataObjectTest_Team'); // query parent class $subteam1Lazy = $teams->find('ID', $subteam1->ID); $this->assertArrayNotHasKey('SubclassDatabaseField_Lazy', $subteam1Lazy->toMap()); $this->assertArrayHasKey('SubclassDatabaseField', $subteam1Lazy->toMap()); }
/** * Loads the related record values into this field. UploadField can be uploaded * in one of three ways: * * - By passing in a list of file IDs in the $value parameter (an array with a single * key 'Files', with the value being the actual array of IDs). * - By passing in an explicit list of File objects in the $record parameter, and * leaving $value blank. * - By passing in a dataobject in the $record parameter, from which file objects * will be extracting using the field name as the relation field. * * Each of these methods will update both the items (list of File objects) and the * field value (list of file ID values). * * @param array $value Array of submitted form data, if submitting from a form * @param array|DataObject|SS_List $record Full source record, either as a DataObject, * SS_List of items, or an array of submitted form data * @return $this Self reference * @throws ValidationException */ public function setValue($value, $record = null) { // If we're not passed a value directly, we can attempt to infer the field // value from the second parameter by inspecting its relations $items = new ArrayList(); // Determine format of presented data if (empty($value) && $record) { // If a record is given as a second parameter, but no submitted values, // then we should inspect this instead for the form values if ($record instanceof DataObject && $record->hasMethod($this->getName())) { // If given a dataobject use reflection to extract details $data = $record->{$this->getName()}(); if ($data instanceof DataObject) { // If has_one, add sole item to default list $items->push($data); } elseif ($data instanceof SS_List) { // For many_many and has_many relations we can use the relation list directly $items = $data; } } elseif ($record instanceof SS_List) { // If directly passing a list then save the items directly $items = $record; } } elseif (!empty($value['Files'])) { // If value is given as an array (such as a posted form), extract File IDs from this $class = $this->getRelationAutosetClass(); $items = DataObject::get($class)->byIDs($value['Files']); } // If javascript is disabled, direct file upload (non-html5 style) can // trigger a single or multiple file submission. Note that this may be // included in addition to re-submitted File IDs as above, so these // should be added to the list instead of operated on independently. if ($uploadedFiles = $this->extractUploadedFileData($value)) { foreach ($uploadedFiles as $tempFile) { $file = $this->saveTemporaryFile($tempFile, $error); if ($file) { $items->add($file); } else { throw new ValidationException($error); } } } // Filter items by what's allowed to be viewed $filteredItems = new ArrayList(); $fileIDs = array(); foreach ($items as $file) { if ($file->exists() && $file->canView()) { $filteredItems->push($file); $fileIDs[] = $file->ID; } } // Filter and cache updated item list $this->items = $filteredItems; // Same format as posted form values for this field. Also ensures that // $this->setValue($this->getValue()); is non-destructive $value = $fileIDs ? array('Files' => $fileIDs) : null; // Set value using parent parent::setValue($value, $record); return $this; }
public function getCMSFields() { $groups = DataObject::get('SilverStripe\\Security\\Group'); $groupsMap = $groups ? $groups->map() : false; $fields = new FieldList(new HiddenField('ID', 'ID'), new CheckboxSetField('Groups', 'Groups', $groupsMap)); return $fields; }
/** * Test that password changes are logged properly */ public function testPasswordChangeLogging() { $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test'); $this->assertNotNull($member); $member->Password = "******"; $member->write(); $member->Password = "******"; $member->write(); $member->Password = "******"; $member->write(); $passwords = DataObject::get("SilverStripe\\Security\\MemberPassword", "\"MemberID\" = {$member->ID}", "\"Created\" DESC, \"ID\" DESC")->getIterator(); $this->assertNotNull($passwords); $passwords->rewind(); $this->assertTrue($passwords->current()->checkPassword('test3'), "Password test3 not found in MemberRecord"); $passwords->next(); $this->assertTrue($passwords->current()->checkPassword('test2'), "Password test2 not found in MemberRecord"); $passwords->next(); $this->assertTrue($passwords->current()->checkPassword('test1'), "Password test1 not found in MemberRecord"); $passwords->next(); $this->assertInstanceOf('SilverStripe\\ORM\\DataObject', $passwords->current()); $this->assertTrue($passwords->current()->checkPassword('1nitialPassword'), "Password 1nitialPassword not found in MemberRecord"); //check we don't retain orphaned records when a member is deleted $member->delete(); $passwords = MemberPassword::get()->filter('MemberID', $member->OldID); $this->assertCount(0, $passwords); }
/** * Cleanup function to reset all the Filename fields. Visit File/fixfiles to call. */ public function fixfiles() { if (!Permission::check('ADMIN')) { return Security::permissionFailure($this); } $files = DataObject::get("File"); foreach ($files as $file) { $file->updateFilesystem(); echo "<li>", $file->Filename; $file->write(); } echo "<p>Done!"; }
/** * Safely query and return all pages queried * * @param array $ids * @return SS_List */ protected function getPages($ids) { // Check empty set if (empty($ids)) { return new ArrayList(); } $recordClass = $this->recordClass; // Bypass translatable filter if (class_exists('Translatable') && $recordClass::has_extension('Translatable')) { Translatable::disable_locale_filter(); } // Bypass versioned filter if ($recordClass::has_extension(Versioned::class)) { // Workaround for get_including_deleted not supporting byIDs filter very well // Ensure we select both stage / live records $pages = Versioned::get_including_deleted($recordClass, array('"RecordID" IN (' . DB::placeholders($ids) . ')' => $ids)); } else { $pages = DataObject::get($recordClass)->byIDs($ids); } if (class_exists('Translatable') && $recordClass::has_extension('Translatable')) { Translatable::enable_locale_filter(); } return $pages; }
/** * Safely get a DataObject from a client-supplied ID and ClassName, checking: argument * validity; existence; and canView permissions. * * @param int $id The ID of the DataObject * @param string $class The Class of the DataObject * @return DataObject The referenced DataObject * @throws SS_HTTPResponse_Exception */ protected function getObject($id, $class) { $id = (int) $id; $class = ClassInfo::class_name($class); if (!$class || !is_subclass_of($class, 'SilverStripe\\ORM\\DataObject') || !Object::has_extension($class, 'SilverStripe\\ORM\\Versioning\\Versioned')) { $this->editForm->httpError(400, _t('AddToCampaign.ErrorGeneral', 'We apologise, but there was an error')); return null; } $object = DataObject::get($class)->byID($id); if (!$object) { $this->editForm->httpError(404, _t('AddToCampaign.ErrorNotFound', 'That {Type} couldn\'t be found', '', ['Type' => $class])); return null; } if (!$object->canView()) { $this->editForm->httpError(403, _t('AddToCampaign.ErrorItemPermissionDenied', 'It seems you don\'t have the necessary permissions to add {ObjectTitle} to a campaign', '', ['ObjectTitle' => $object->Title])); return null; } return $object; }
/** * Return the first item matching the given query. * All calls to get_one() are cached. * * @param string $callerClass The class of objects to be returned * @param string|array $filter A filter to be inserted into the WHERE clause. * Supports parameterised queries. See SQLSelect::addWhere() for syntax examples. * @param boolean $cache Use caching * @param string $orderby A sort expression to be inserted into the ORDER BY clause. * * @return DataObject The first item matching the query */ public static function get_one($callerClass, $filter = "", $cache = true, $orderby = "") { $SNG = singleton($callerClass); $cacheComponents = array($filter, $orderby, $SNG->extend('cacheKeyComponent')); $cacheKey = md5(var_export($cacheComponents, true)); // Flush destroyed items out of the cache if ($cache && isset(self::$_cache_get_one[$callerClass][$cacheKey]) && self::$_cache_get_one[$callerClass][$cacheKey] instanceof DataObject && self::$_cache_get_one[$callerClass][$cacheKey]->destroyed) { self::$_cache_get_one[$callerClass][$cacheKey] = false; } $item = null; if (!$cache || !isset(self::$_cache_get_one[$callerClass][$cacheKey])) { $dl = DataObject::get($callerClass)->where($filter)->sort($orderby); $item = $dl->first(); if ($cache) { self::$_cache_get_one[$callerClass][$cacheKey] = $item; if (!self::$_cache_get_one[$callerClass][$cacheKey]) { self::$_cache_get_one[$callerClass][$cacheKey] = false; } } } return $cache ? self::$_cache_get_one[$callerClass][$cacheKey] : $item; }
public function testBrokenLateStaticBindingStyle() { // If you call DataObject::get() you have to pass a first argument $this->setExpectedException('InvalidArgumentException'); DataObject::get(); }
public function load($filepath) { increase_time_limit_to(3600); increase_memory_limit_to('512M'); //get all instances of the to be imported data object if ($this->deleteExistingRecords) { DataObject::get($this->objectClass)->removeAll(); } return $this->processAll($filepath); }
public function testArchiveVersion() { // In 2005 this file was created DBDatetime::set_mock_now('2005-01-01 00:00:00'); $testPage = new VersionedTest_Subclass(); $testPage->Title = 'Archived page'; $testPage->Content = 'This is the content from 2005'; $testPage->ExtraField = '2005'; $testPage->write(); // In 2007 we updated it DBDatetime::set_mock_now('2007-01-01 00:00:00'); $testPage->Content = "It's 2007 already!"; $testPage->ExtraField = '2007'; $testPage->write(); // In 2009 we updated it again DBDatetime::set_mock_now('2009-01-01 00:00:00'); $testPage->Content = "I'm enjoying 2009"; $testPage->ExtraField = '2009'; $testPage->write(); // End mock, back to the present day:) DBDatetime::clear_mock_now(); // Test 1 - 2006 Content singleton('VersionedTest_Subclass')->flushCache(true); Versioned::set_reading_mode('Archive.2006-01-01 00:00:00'); $testPage2006 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first(); $this->assertInstanceOf("VersionedTest_Subclass", $testPage2006); $this->assertEquals("2005", $testPage2006->ExtraField); $this->assertEquals("This is the content from 2005", $testPage2006->Content); // Test 2 - 2008 Content singleton('VersionedTest_Subclass')->flushCache(true); Versioned::set_reading_mode('Archive.2008-01-01 00:00:00'); $testPage2008 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first(); $this->assertInstanceOf("VersionedTest_Subclass", $testPage2008); $this->assertEquals("2007", $testPage2008->ExtraField); $this->assertEquals("It's 2007 already!", $testPage2008->Content); // Test 3 - Today singleton('VersionedTest_Subclass')->flushCache(true); Versioned::set_reading_mode('Stage.Stage'); $testPageCurrent = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first(); $this->assertInstanceOf("VersionedTest_Subclass", $testPageCurrent); $this->assertEquals("2009", $testPageCurrent->ExtraField); $this->assertEquals("I'm enjoying 2009", $testPageCurrent->Content); }
/** * Helper method for applicablePages() methods. Acts as a skeleton implementation. * * @param array $ids The IDs passed to applicablePages * @param string $methodName The canXXX() method to call on each page to check if the action is applicable * @param bool $checkStagePages Set to true if you want to check stage pages * @param bool $checkLivePages Set to true if you want to check live pages (e.g, for deleted-from-draft) * @return array */ public function applicablePagesHelper($ids, $methodName, $checkStagePages = true, $checkLivePages = true) { if (!is_array($ids)) { user_error("Bad \$ids passed to applicablePagesHelper()", E_USER_WARNING); } if (!is_string($methodName)) { user_error("Bad \$methodName passed to applicablePagesHelper()", E_USER_WARNING); } $applicableIDs = array(); $managedClass = $this->managedClass; $draftPages = DataObject::get($managedClass)->byIDs($ids); // Filter out the live-only ids $onlyOnLive = array_fill_keys($ids, true); if ($checkStagePages) { foreach ($draftPages as $obj) { unset($onlyOnLive[$obj->ID]); if ($obj->{$methodName}()) { $applicableIDs[] = $obj->ID; } } } $onlyOnLive = array_keys($onlyOnLive); if ($checkLivePages && $onlyOnLive && Object::has_extension($managedClass, 'SilverStripe\\ORM\\Versioning\\Versioned')) { // Get the pages that only exist on live (deleted from stage) $livePages = Versioned::get_by_stage($managedClass, "Live")->byIDs($onlyOnLive); foreach ($livePages as $obj) { if ($obj->{$methodName}()) { $applicableIDs[] = $obj->ID; } } } return $applicableIDs; }
/** * Get a set of class instances by the given stage. * * @param string $class The name of the class. * @param string $stage The name of the stage. * @param string $filter A filter to be inserted into the WHERE clause. * @param string $sort A sort expression to be inserted into the ORDER BY clause. * @param string $join Deprecated, use leftJoin($table, $joinClause) instead * @param int $limit A limit on the number of records returned from the database. * @param string $containerClass The container class for the result set (default is DataList) * * @return DataList A modified DataList designated to the specified stage */ public static function get_by_stage($class, $stage, $filter = '', $sort = '', $join = '', $limit = null, $containerClass = 'SilverStripe\\ORM\\DataList') { $result = DataObject::get($class, $filter, $sort, $join, $limit, $containerClass); return $result->setDataQueryParam(array('Versioned.mode' => 'stage', 'Versioned.stage' => $stage)); }