public function scaffoldFormField($title = null, $params = null)
 {
     if (empty($this->object)) {
         return null;
     }
     $relationName = substr($this->name, 0, -2);
     $hasOneClass = $this->object->hasOneComponent($relationName);
     if (empty($hasOneClass)) {
         return null;
     }
     $hasOneSingleton = singleton($hasOneClass);
     if ($hasOneSingleton instanceof File) {
         $field = new UploadField($relationName, $title);
         if ($hasOneSingleton instanceof Image) {
             $field->setAllowedFileCategories('image/supported');
         }
         return $field;
     }
     // Build selector / numeric field
     $titleField = $hasOneSingleton->hasField('Title') ? "Title" : "Name";
     $list = DataList::create($hasOneClass);
     // Don't scaffold a dropdown for large tables, as making the list concrete
     // might exceed the available PHP memory in creating too many DataObject instances
     if ($list->count() < 100) {
         $field = new DropdownField($this->name, $title, $list->map('ID', $titleField));
         $field->setEmptyString(' ');
     } else {
         $field = new NumericField($this->name, $title);
     }
     return $field;
 }
 /**
  * @param string $class
  * @param GridField $gridField
  * @param DataObject $record
  * @param RequestHandler $requestHandler
  */
 public function updateItemRequestClass(&$class, $gridField, $record, $requestHandler)
 {
     // Conditionally use a versioned item handler
     if ($record && $record->has_extension('SilverStripe\\ORM\\Versioning\\Versioned')) {
         $class = 'SilverStripe\\ORM\\Versioning\\VersionedGridFieldItemRequest';
     }
 }
 /**
  * Adds the item to this relation.
  *
  * It does so by setting the relationFilters.
  *
  * @param $item The DataObject to be added, or its ID
  */
 public function add($item)
 {
     if (is_numeric($item)) {
         $item = DataObject::get_by_id($this->dataClass, $item);
     } else {
         if (!$item instanceof $this->dataClass) {
             user_error("PolymorphicHasManyList::add() expecting a {$this->dataClass} object, or ID value", E_USER_ERROR);
         }
     }
     $foreignID = $this->getForeignID();
     // Validate foreignID
     if (!$foreignID) {
         user_error("PolymorphicHasManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
         return;
     }
     if (is_array($foreignID)) {
         user_error("PolymorphicHasManyList::add() can't be called on a list linked to mulitple foreign IDs", E_USER_WARNING);
         return;
     }
     $foreignKey = $this->foreignKey;
     $classForeignKey = $this->classForeignKey;
     $item->{$foreignKey} = $foreignID;
     $item->{$classForeignKey} = $this->getForeignClass();
     $item->write();
 }
 public function testMultipleRowInsert()
 {
     $query = SQLInsert::create('"SQLInsertTestBase"');
     $query->addRow(array('"Title"' => 'First Object', '"Age"' => 10, '"Description"' => 'First the worst'));
     $query->addRow(array('"Title"' => 'Second object', '"Age"' => 12));
     $sql = $query->sql($parameters);
     // Only test this case if using the default query builder
     if (get_class(DB::get_conn()->getQueryBuilder()) === 'SilverStripe\\ORM\\Connect\\DBQueryBuilder') {
         $this->assertSQLEquals('INSERT INTO "SQLInsertTestBase" ("Title", "Age", "Description") VALUES (?, ?, ?), (?, ?, ?)', $sql);
     }
     $this->assertEquals(array('First Object', 10, 'First the worst', 'Second object', 12, null), $parameters);
     $query->execute();
     $this->assertEquals(2, DB::affected_rows());
     // Check inserted objects are correct
     $firstObject = DataObject::get_one('SQLInsertTestBase', array('"Title"' => 'First Object'), false);
     $this->assertNotEmpty($firstObject);
     $this->assertEquals($firstObject->Title, 'First Object');
     $this->assertEquals($firstObject->Age, 10);
     $this->assertEquals($firstObject->Description, 'First the worst');
     $secondObject = DataObject::get_one('SQLInsertTestBase', array('"Title"' => 'Second object'), false);
     $this->assertNotEmpty($secondObject);
     $this->assertEquals($secondObject->Title, 'Second object');
     $this->assertEquals($secondObject->Age, 12);
     $this->assertEmpty($secondObject->Description);
 }
 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 fieldLabels($includerelations = true)
 {
     $labels = parent::fieldLabels($includerelations);
     $labels['Title'] = _t('PermissionRole.Title', 'Title');
     $labels['OnlyAdminCanApply'] = _t('PermissionRole.OnlyAdminCanApply', 'Only admin can apply', 'Checkbox to limit which user can apply this role');
     return $labels;
 }
 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 processRecord($record, $columnMap, &$results, $preview = false)
 {
     // We match by 'Code', the ID property is confusing the importer
     if (isset($record['ID'])) {
         unset($record['ID']);
     }
     $objID = parent::processRecord($record, $columnMap, $results, $preview);
     $group = DataObject::get_by_id($this->objectClass, $objID);
     // set group hierarchies - we need to do this after all records
     // are imported to avoid missing "early" references to parents
     // which are imported later on in the CSV file.
     if (isset($record['ParentCode']) && $record['ParentCode']) {
         $parentGroup = DataObject::get_one('SilverStripe\\Security\\Group', array('"Group"."Code"' => $record['ParentCode']));
         if ($parentGroup) {
             $group->ParentID = $parentGroup->ID;
             $group->write();
         }
     }
     // set permission codes - these are all additive, meaning
     // existing permissions arent cleared.
     if (isset($record['PermissionCodes']) && $record['PermissionCodes']) {
         foreach (explode(',', $record['PermissionCodes']) as $code) {
             $p = DataObject::get_one('SilverStripe\\Security\\Permission', array('"Permission"."Code"' => $code, '"Permission"."GroupID"' => $group->ID));
             if (!$p) {
                 $p = new Permission(array('Code' => $code));
                 $p->write();
             }
             $group->Permissions()->add($p);
         }
     }
     return $objID;
 }
 public function testApplyReplationDeepInheretence()
 {
     //test has_one relation
     $newDQ = new DataQuery('DataQueryTest_E');
     //apply a relation to a relation from an ancestor class
     $newDQ->applyRelation('TestA');
     $this->assertTrue($newDQ->query()->isJoinedTo('DataQueryTest_C'));
     $this->assertContains('"DataQueryTest_A"."ID" = "DataQueryTest_C"."TestAID"', $newDQ->sql($params));
     //test many_many relation
     //test many_many with separate inheritance
     $newDQ = new DataQuery('DataQueryTest_C');
     $baseDBTable = DataObject::getSchema()->baseDataTable('DataQueryTest_C');
     $newDQ->applyRelation('ManyTestAs');
     //check we are "joined" to the DataObject's table (there is no distinction between FROM or JOIN clauses)
     $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable));
     //check we are explicitly selecting "FROM" the DO's table
     $this->assertContains("FROM \"{$baseDBTable}\"", $newDQ->sql());
     //test many_many with shared inheritance
     $newDQ = new DataQuery('DataQueryTest_E');
     $baseDBTable = DataObject::getSchema()->baseDataTable('DataQueryTest_E');
     //check we are "joined" to the DataObject's table (there is no distinction between FROM or JOIN clauses)
     $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable));
     //check we are explicitly selecting "FROM" the DO's table
     $this->assertContains("FROM \"{$baseDBTable}\"", $newDQ->sql(), 'The FROM clause is missing from the query');
     $newDQ->applyRelation('ManyTestGs');
     //confirm we are still joined to the base table
     $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable));
     //double check it is the "FROM" clause
     $this->assertContains("FROM \"{$baseDBTable}\"", $newDQ->sql(), 'The FROM clause has been removed from the query');
     //another (potentially less crude check) for checking "FROM" clause
     $fromTables = $newDQ->query()->getFrom();
     $this->assertEquals('"' . $baseDBTable . '"', $fromTables[$baseDBTable]);
 }
 public function processRecord($record, $columnMap, &$results, $preview = false)
 {
     $objID = parent::processRecord($record, $columnMap, $results, $preview);
     $_cache_groupByCode = array();
     // Add to predefined groups
     /** @var Member $member */
     $member = DataObject::get_by_id($this->objectClass, $objID);
     foreach ($this->groups as $group) {
         // TODO This isnt the most memory effective way to add members to a group
         $member->Groups()->add($group);
     }
     // Add to groups defined in CSV
     if (isset($record['Groups']) && $record['Groups']) {
         $groupCodes = explode(',', $record['Groups']);
         foreach ($groupCodes as $groupCode) {
             $groupCode = Convert::raw2url($groupCode);
             if (!isset($_cache_groupByCode[$groupCode])) {
                 $group = Group::get()->filter('Code', $groupCode)->first();
                 if (!$group) {
                     $group = new Group();
                     $group->Code = $groupCode;
                     $group->Title = $groupCode;
                     $group->write();
                 }
                 $member->Groups()->add($group);
                 $_cache_groupByCode[$groupCode] = $group;
             }
         }
     }
     $member->destroy();
     unset($member);
     return $objID;
 }
 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');
 }
 /**
  * @param bool $includerelations Indicate if the labels returned include relation fields
  * @return array
  */
 public function fieldLabels($includerelations = true)
 {
     $labels = parent::fieldLabels($includerelations);
     $labels['Email'] = _t('LoginAttempt.Email', 'Email Address');
     $labels['Status'] = _t('LoginAttempt.Status', 'Status');
     $labels['IP'] = _t('LoginAttempt.IP', 'IP Address');
     return $labels;
 }
 public function getValue()
 {
     $id = $this->getIDValue();
     $class = $this->getClassValue();
     if ($id && $class && is_subclass_of($class, 'SilverStripe\\ORM\\DataObject')) {
         return DataObject::get_by_id($class, $id);
     }
     return null;
 }
 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 validate()
 {
     $result = parent::validate();
     // Check that new code doesn't increase privileges, unless an admin is editing.
     $privilegedCodes = Permission::config()->privileged_permissions;
     if ($this->Code && in_array($this->Code, $privilegedCodes) && !Permission::check('ADMIN')) {
         $result->error(sprintf(_t('PermissionRoleCode.PermsError', 'Can\'t assign code "%s" with privileged permissions (requires ADMIN access)'), $this->Code));
     }
     return $result;
 }
 /**
  * Test DataObject::composite_fields() and DataObject::is_composite_field()
  */
 public function testCompositeFieldMetaDataFunctions()
 {
     $this->assertEquals('Money', DataObject::is_composite_field('DBCompositeTest_DataObject', 'MyMoney'));
     $this->assertFalse(DataObject::is_composite_field('DBCompositeTest_DataObject', 'Title'));
     $this->assertEquals(array('MyMoney' => 'Money', 'OverriddenMoney' => 'Money'), DataObject::composite_fields('DBCompositeTest_DataObject'));
     $this->assertEquals('Money', DataObject::is_composite_field('SubclassedDBFieldObject', 'MyMoney'));
     $this->assertEquals('Money', DataObject::is_composite_field('SubclassedDBFieldObject', 'OtherMoney'));
     $this->assertFalse(DataObject::is_composite_field('SubclassedDBFieldObject', 'Title'));
     $this->assertFalse(DataObject::is_composite_field('SubclassedDBFieldObject', 'OtherField'));
     $this->assertEquals(array('MyMoney' => 'Money', 'OtherMoney' => 'Money', 'OverriddenMoney' => 'Money'), DataObject::composite_fields('SubclassedDBFieldObject'));
 }
 /**
  * Test DataObject::composite_fields() and DataObject::is_composite_field()
  */
 public function testCompositeFieldMetaDataFunctions()
 {
     $schema = DataObject::getSchema();
     $this->assertEquals('Money', $schema->compositeField(DBCompositeTest_DataObject::class, 'MyMoney'));
     $this->assertNull($schema->compositeField(DBCompositeTest_DataObject::class, 'Title'));
     $this->assertEquals(array('MyMoney' => 'Money', 'OverriddenMoney' => 'Money'), $schema->compositeFields(DBCompositeTest_DataObject::class));
     $this->assertEquals('Money', $schema->compositeField(SubclassedDBFieldObject::class, 'MyMoney'));
     $this->assertEquals('Money', $schema->compositeField(SubclassedDBFieldObject::class, 'OtherMoney'));
     $this->assertNull($schema->compositeField(SubclassedDBFieldObject::class, 'Title'));
     $this->assertNull($schema->compositeField(SubclassedDBFieldObject::class, 'OtherField'));
     $this->assertEquals(array('MyMoney' => 'Money', 'OtherMoney' => 'Money', 'OverriddenMoney' => 'Money'), $schema->compositeFields(SubclassedDBFieldObject::class));
 }
 public function testCleartextPasswordsAreHashedWithDefaultAlgo()
 {
     $loader = new MemberCsvBulkLoader();
     $results = $loader->load($this->getCurrentRelativePath() . '/MemberCsvBulkLoaderTest_cleartextpws.csv');
     $member = $results->Created()->First();
     $memberID = $member->ID;
     DataObject::flush_and_destroy_cache();
     $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $memberID);
     // TODO Direct getter doesn't work, wtf!
     $this->assertEquals(Security::config()->password_encryption_algorithm, $member->getField('PasswordEncryption'));
     $result = $member->checkPassword('mypassword');
     $this->assertTrue($result->valid());
 }
 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()');
 }
 public function testSQLInsert()
 {
     $factory = new FixtureFactory();
     $relPath = ltrim(FRAMEWORK_DIR . '/tests/testing/YamlFixtureTest.yml', '/');
     $fixture = Injector::inst()->create('SilverStripe\\Dev\\YamlFixture', $relPath);
     $fixture->writeInto($factory);
     $this->assertGreaterThan(0, $factory->getId("YamlFixtureTest_DataObject", "testobject1"));
     $object1 = DataObject::get_by_id("YamlFixtureTest_DataObject", $factory->getId("YamlFixtureTest_DataObject", "testobject1"));
     $this->assertTrue($object1->ManyManyRelation()->Count() == 2, "Should be two items in this relationship");
     $this->assertGreaterThan(0, $factory->getId("YamlFixtureTest_DataObject", "testobject2"));
     $object2 = DataObject::get_by_id("YamlFixtureTest_DataObject", $factory->getId("YamlFixtureTest_DataObject", "testobject2"));
     $this->assertTrue($object2->ManyManyRelation()->Count() == 1, "Should be one item in this relationship");
 }
 public function testBasicUpdate()
 {
     $query = SQLUpdate::create()->setTable('"SQLUpdateTestBase"')->assign('"Description"', 'Description 1a')->addWhere(array('"Title" = ?' => 'Object 1'));
     $sql = $query->sql($parameters);
     // Check SQL
     $this->assertSQLEquals('UPDATE "SQLUpdateTestBase" SET "Description" = ? WHERE ("Title" = ?)', $sql);
     $this->assertEquals(array('Description 1a', 'Object 1'), $parameters);
     // Check affected rows
     $query->execute();
     $this->assertEquals(1, DB::affected_rows());
     // Check item updated
     $item = DataObject::get_one('SQLUpdateTestBase', array('"Title"' => 'Object 1'));
     $this->assertEquals('Description 1a', $item->Description);
 }
 public function testRun()
 {
     $m = new Member();
     $m->Password = '******';
     $m->PasswordEncryption = 'none';
     $m->write();
     $t = new EncryptAllPasswordsTask();
     $t->run(null);
     $m = DataObject::get_by_id('SilverStripe\\Security\\Member', $m->ID);
     $this->assertEquals($m->PasswordEncryption, 'blowfish');
     $this->assertNotEquals($m->Password, 'plain');
     $result = $m->checkPassword('plain');
     $this->assertTrue($result->valid());
 }
 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);
             }
         }
     }
 }
 /**
  * CMS-specific functionality: Passes through navigation breadcrumbs
  * to the template, and includes the currently edited record (if any).
  * see {@link LeftAndMain->Breadcrumbs()} for details.
  *
  * @param boolean $unlinked
  * @return ArrayList
  */
 public function Breadcrumbs($unlinked = false)
 {
     if (!$this->popupController->hasMethod('Breadcrumbs')) {
         return null;
     }
     /** @var ArrayList $items */
     $items = $this->popupController->Breadcrumbs($unlinked);
     if ($this->record && $this->record->ID) {
         $title = $this->record->Title ? $this->record->Title : "#{$this->record->ID}";
         $items->push(new ArrayData(array('Title' => $title, 'Link' => $this->Link())));
     } else {
         $items->push(new ArrayData(array('Title' => sprintf(_t('GridField.NewRecord', 'New %s'), $this->record->i18n_singular_name()), 'Link' => false)));
     }
     return $items;
 }
 public function testNoLegacyPasswordHashMigrationOnIncompatibleAlgorithm()
 {
     Config::inst()->update('SilverStripe\\Security\\PasswordEncryptor', 'encryptors', array('crc32' => array('SilverStripe\\Security\\PasswordEncryptor_PHPHash' => 'crc32')));
     $field = Member::config()->unique_identifier_field;
     $member = new Member();
     $member->{$field} = '*****@*****.**';
     $member->PasswordEncryption = "crc32";
     $member->Password = "******";
     $member->write();
     $data = array('Email' => $member->{$field}, 'Password' => 'mypassword');
     MemberAuthenticator::authenticate($data);
     $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member->ID);
     $this->assertEquals($member->PasswordEncryption, "crc32");
     $result = $member->checkPassword('mypassword');
     $this->assertTrue($result->valid());
 }
 public function testDuplicateManyManyClasses()
 {
     //create new test classes below
     $one = new DataObjectDuplicateTestClass1();
     $two = new DataObjectDuplicateTestClass2();
     $three = new DataObjectDuplicateTestClass3();
     //set some simple fields
     $text1 = "Test Text 1";
     $text2 = "Test Text 2";
     $text3 = "Test Text 3";
     $one->text = $text1;
     $two->text = $text2;
     $three->text = $text3;
     //write the to DB
     $one->write();
     $two->write();
     $three->write();
     //create relations
     $one->twos()->add($two);
     $one->threes()->add($three);
     $one = DataObject::get_by_id("DataObjectDuplicateTestClass1", $one->ID);
     $two = DataObject::get_by_id("DataObjectDuplicateTestClass2", $two->ID);
     $three = DataObject::get_by_id("DataObjectDuplicateTestClass3", $three->ID);
     //test duplication
     $oneCopy = $one->duplicate();
     $twoCopy = $two->duplicate();
     $threeCopy = $three->duplicate();
     $oneCopy = DataObject::get_by_id("DataObjectDuplicateTestClass1", $oneCopy->ID);
     $twoCopy = DataObject::get_by_id("DataObjectDuplicateTestClass2", $twoCopy->ID);
     $threeCopy = DataObject::get_by_id("DataObjectDuplicateTestClass3", $threeCopy->ID);
     $this->assertNotNull($oneCopy, "Copy of 1 exists");
     $this->assertNotNull($twoCopy, "Copy of 2 exists");
     $this->assertNotNull($threeCopy, "Copy of 3 exists");
     $this->assertEquals($text1, $oneCopy->text);
     $this->assertEquals($text2, $twoCopy->text);
     $this->assertEquals($text3, $threeCopy->text);
     $this->assertNotEquals($one->twos()->Count(), $oneCopy->twos()->Count(), "Many-to-one relation not copied (has_many)");
     $this->assertEquals($one->threes()->Count(), $oneCopy->threes()->Count(), "Object has the correct number of relations");
     $this->assertEquals($three->ones()->Count(), $threeCopy->ones()->Count(), "Object has the correct number of relations");
     $this->assertEquals($one->ID, $twoCopy->one()->ID, "Match between relation of copy and the original");
     $this->assertEquals(0, $oneCopy->twos()->Count(), "Many-to-one relation not copied (has_many)");
     $this->assertEquals($three->ID, $oneCopy->threes()->First()->ID, "Match between relation of copy and the original");
     $this->assertEquals($one->ID, $threeCopy->ones()->First()->ID, "Match between relation of copy and the original");
 }
 /**
  * Get the base dataclass for the list of subclasses
  *
  * @return string
  */
 public function getBaseClass()
 {
     // Use explicit base class
     if ($this->baseClass) {
         return $this->baseClass;
     }
     // Default to the basename of the record
     $schema = DataObject::getSchema();
     if ($this->record) {
         return $schema->baseDataClass($this->record);
     }
     // During dev/build only the table is assigned
     $tableClass = $schema->tableClass($this->getTable());
     if ($tableClass && ($baseClass = $schema->baseDataClass($tableClass))) {
         return $baseClass;
     }
     // Fallback to global default
     return 'SilverStripe\\ORM\\DataObject';
 }
 /**
  * Set value of a single composite field
  *
  * @param string $field
  * @param mixed $value
  * @param bool $markChanged
  * @return $this
  */
 public function setField($field, $value, $markChanged = true)
 {
     $this->objCacheClear();
     // Skip non-db fields
     if (!$this->hasField($field)) {
         return $this;
     }
     // Set changed
     if ($markChanged) {
         $this->isChanged = true;
     }
     // Set bound object
     if ($this->record instanceof DataObject) {
         $key = $this->getName() . $field;
         $this->record->setField($key, $value);
         return $this;
     }
     // Set local record
     $this->record[$field] = $value;
     return $this;
 }
 /**
  * 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');
 }