public function testHasOnes()
 {
     /** @var DataDifferencerTest_Object $obj1 */
     $obj1 = $this->objFromFixture('DataDifferencerTest_Object', 'obj1');
     $image1 = $this->objFromFixture('Image', 'image1');
     $image2 = $this->objFromFixture('Image', 'image2');
     $relobj1 = $this->objFromFixture('DataDifferencerTest_HasOneRelationObject', 'relobj1');
     $relobj2 = $this->objFromFixture('DataDifferencerTest_HasOneRelationObject', 'relobj2');
     // create a new version
     $beforeVersion = $obj1->Version;
     $obj1->ImageID = $image2->ID;
     $obj1->HasOneRelationID = $relobj2->ID;
     $obj1->write();
     $afterVersion = $obj1->Version;
     $this->assertNotEquals($beforeVersion, $afterVersion);
     /** @var DataDifferencerTest_Object $obj1v1 */
     $obj1v1 = Versioned::get_version('DataDifferencerTest_Object', $obj1->ID, $beforeVersion);
     /** @var DataDifferencerTest_Object $obj1v2 */
     $obj1v2 = Versioned::get_version('DataDifferencerTest_Object', $obj1->ID, $afterVersion);
     $differ = new DataDifferencer($obj1v1, $obj1v2);
     $obj1Diff = $differ->diffedData();
     $this->assertContains($image1->Name, $obj1Diff->getField('Image'));
     $this->assertContains($image2->Name, $obj1Diff->getField('Image'));
     $this->assertContains('<ins>obj2</ins><del>obj1</del>', str_replace(' ', '', $obj1Diff->getField('HasOneRelationID')));
 }
 /**
  * @param int $from
  * @param int $to
  *
  * @return string
  */
 public function humanizedChanges($from, $to)
 {
     if (!$from) {
         return _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.UPLOADEDFILE', "Uploaded file");
     }
     $fromRecord = Versioned::get_version($this->owner->class, $this->owner->ID, $from);
     $toRecord = Versioned::get_version($this->owner->class, $this->owner->ID, $to);
     $diff = new DataDifferencer($fromRecord, $toRecord);
     $changes = $diff->changedFieldNames();
     $k = array_search('LastEdited', $changes);
     if ($k !== false) {
         unset($changes[$k]);
     }
     $output = array();
     foreach ($changes as $change) {
         $human = $change;
         if ($change == "ParentID") {
             // updated folder ID
             $human = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdminFile.MOVEDFOLDER', "Moved file");
         } elseif ($change == 'Title') {
             $human = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdminFile.RENAMEDTITLE', "Updated title to ") . $fromRecord->Title;
         } elseif ($change == 'Name') {
             $human = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdminFile.RENAMEDFILE', "Renamed file to ") . $fromRecord->Filename;
         } elseif ($change == 'File') {
             // check to make sure the files are actually different
             if ($fromRecord->getHash() != $toRecord->getHash()) {
                 $human = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdminFile.RENAMEDFILE', "Replaced file");
             } else {
                 $human = false;
             }
         } else {
             $human = false;
         }
         if ($human) {
             $output[] = $human;
         }
     }
     return implode(", ", $output);
 }
 public function testGetVersionWhenClassnameChanged()
 {
     $obj = new VersionedTest_DataObject();
     $obj->Name = "test";
     $obj->write();
     $obj->Name = "test2";
     $obj->ClassName = "VersionedTest_Subclass";
     $obj->write();
     $subclassVersion = $obj->Version;
     $obj->Name = "test3";
     $obj->ClassName = "VersionedTest_DataObject";
     $obj->write();
     // We should be able to pass the subclass and still get the correct class back
     $obj2 = Versioned::get_version("VersionedTest_Subclass", $obj->ID, $subclassVersion);
     $this->assertInstanceOf("VersionedTest_Subclass", $obj2);
     $this->assertEquals("test2", $obj2->Name);
     $obj3 = Versioned::get_latest_version("VersionedTest_Subclass", $obj->ID);
     $this->assertEquals("test3", $obj3->Name);
     $this->assertInstanceOf("VersionedTest_DataObject", $obj3);
 }
 public function testLazyLoadedFieldsOnVersionedRecords()
 {
     // Save another record, sanity check that we're getting the right one
     $obj2 = new VersionedTest_Subclass();
     $obj2->Name = "test2";
     $obj2->ExtraField = "foo2";
     $obj2->write();
     // Save the actual inspected record
     $obj1 = new VersionedTest_Subclass();
     $obj1->Name = "test";
     $obj1->ExtraField = "foo";
     $obj1->write();
     $version1 = $obj1->Version;
     $obj1->Name = "test2";
     $obj1->ExtraField = "baz";
     $obj1->write();
     $version2 = $obj1->Version;
     $reloaded = Versioned::get_version('VersionedTest_Subclass', $obj1->ID, $version1);
     $this->assertEquals($reloaded->Name, 'test');
     $this->assertEquals($reloaded->ExtraField, 'foo');
     $reloaded = Versioned::get_version('VersionedTest_Subclass', $obj1->ID, $version2);
     $this->assertEquals($reloaded->Name, 'test2');
     $this->assertEquals($reloaded->ExtraField, 'baz');
     $reloaded = Versioned::get_latest_version('VersionedTest_Subclass', $obj1->ID);
     $this->assertEquals($reloaded->Version, $version2);
     $this->assertEquals($reloaded->Name, 'test2');
     $this->assertEquals($reloaded->ExtraField, 'baz');
     $allVersions = Versioned::get_all_versions('VersionedTest_Subclass', $obj1->ID);
     $this->assertEquals(2, $allVersions->Count());
     $this->assertEquals($allVersions->First()->Version, $version1);
     $this->assertEquals($allVersions->First()->Name, 'test');
     $this->assertEquals($allVersions->First()->ExtraField, 'foo');
     $this->assertEquals($allVersions->Last()->Version, $version2);
     $this->assertEquals($allVersions->Last()->Name, 'test2');
     $this->assertEquals($allVersions->Last()->ExtraField, 'baz');
     $obj1->delete();
 }
 /**
  * Compare two version, and return the diff between them.
  *
  * @param string $from The version to compare from.
  * @param string $to The version to compare to.
  *
  * @return DataObject
  */
 public function compareVersions($from, $to)
 {
     $owner = $this->owner;
     $fromRecord = Versioned::get_version($owner->class, $owner->ID, $from);
     $toRecord = Versioned::get_version($owner->class, $owner->ID, $to);
     $diff = new DataDifferencer($fromRecord, $toRecord);
     return $diff->diffedData();
 }
 /**
  * @param array $context
  * @return Form
  * @throws InvalidArgumentException
  */
 public function getFileHistoryForm($context)
 {
     // Check context
     if (!isset($context['RecordID']) || !isset($context['RecordVersion'])) {
         throw new InvalidArgumentException("Missing RecordID / RecordVersion for this form");
     }
     $id = $context['RecordID'];
     $versionId = $context['RecordVersion'];
     if (!$id || !$versionId) {
         return $this->httpError(404);
     }
     /** @var File $file */
     $file = Versioned::get_version(File::class, $id, $versionId);
     if (!$file) {
         return $this->httpError(404);
     }
     if (!$file->canView()) {
         $this->httpError(403, _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.ErrorItemPermissionDenied', 'You don\'t have the necessary permissions to modify {ObjectTitle}', '', ['ObjectTitle' => $file->i18n_singular_name()]));
         return null;
     }
     $effectiveContext = array_merge($context, ['Record' => $file]);
     /** @var FormFactory $scaffolder */
     $scaffolder = Injector::inst()->get(FileHistoryFormFactory::class);
     $form = $scaffolder->getForm($this, 'fileHistoryForm', $effectiveContext);
     // Configure form to respond to validation errors with form schema
     // if requested via react.
     $form->setValidationResponseCallback(function (ValidationResult $errors) use($form, $id, $versionId) {
         $schemaId = Controller::join_links($this->Link('schema/fileHistoryForm'), $id, $versionId);
         return $this->getSchemaResponse($schemaId, $form, $errors);
     });
     return $form;
 }