public function setUp()
 {
     parent::setUp();
     $this->logInWithPermission('ADMIN');
     Versioned::set_stage(Versioned::DRAFT);
     // Set backend root to /AssetFieldTest
     AssetStoreTest_SpyStore::activate('AssetFieldTest');
     $create = function ($path) {
         Filesystem::makeFolder(dirname($path));
         $fh = fopen($path, "w+");
         fwrite($fh, str_repeat('x', 1000000));
         fclose($fh);
     };
     // Write all DBFile references
     foreach (AssetFieldTest_Object::get() as $object) {
         $path = AssetStoreTest_SpyStore::getLocalPath($object->File);
         $create($path);
     }
     // Create a test files for each of the fixture references
     $files = File::get()->exclude('ClassName', 'SilverStripe\\Assets\\Folder');
     foreach ($files as $file) {
         $path = AssetStoreTest_SpyStore::getLocalPath($file);
         $create($path);
     }
 }
Exemplo n.º 2
0
 public function setUp()
 {
     parent::setUp();
     $this->logInWithPermission('ADMIN');
     Versioned::set_stage(Versioned::DRAFT);
     // Set backend root to /ImageTest
     AssetStoreTest_SpyStore::activate('FileTest');
     // Create a test folders for each of the fixture references
     $folderIDs = $this->allFixtureIDs('Folder');
     foreach ($folderIDs as $folderID) {
         $folder = DataObject::get_by_id('Folder', $folderID);
         $filePath = ASSETS_PATH . '/FileTest/' . $folder->getFilename();
         SS_Filesystem::makeFolder($filePath);
     }
     // Create a test files for each of the fixture references
     $fileIDs = $this->allFixtureIDs('File');
     foreach ($fileIDs as $fileID) {
         $file = DataObject::get_by_id('File', $fileID);
         $root = ASSETS_PATH . '/FileTest/';
         if ($folder = $file->Parent()) {
             $root .= $folder->getFilename();
         }
         $path = $root . substr($file->getHash(), 0, 10) . '/' . basename($file->getFilename());
         SS_Filesystem::makeFolder(dirname($path));
         $fh = fopen($path, "w+");
         fwrite($fh, str_repeat('x', 1000000));
         fclose($fh);
     }
     // Conditional fixture creation in case the 'cms' module is installed
     if (class_exists('SilverStripe\\CMS\\Model\\ErrorPage')) {
         $page = new ErrorPage(array('Title' => 'Page not Found', 'ErrorCode' => 404));
         $page->write();
         $page->copyVersionToStage('Stage', 'Live');
     }
 }
 /**
  * Perform migration
  *
  * @param string $base Absolute base path (parent of assets folder). Will default to BASE_PATH
  * @return int Number of files successfully migrated
  */
 public function run($base = null)
 {
     if (empty($base)) {
         $base = BASE_PATH;
     }
     // Check if the File dataobject has a "Filename" field.
     // If not, cannot migrate
     /** @skipUpgrade */
     if (!DB::get_schema()->hasField('File', 'Filename')) {
         return 0;
     }
     // Set max time and memory limit
     increase_time_limit_to();
     increase_memory_limit_to();
     // Loop over all files
     $count = 0;
     $originalState = Versioned::get_reading_mode();
     Versioned::set_stage(Versioned::DRAFT);
     $filenameMap = $this->getFilenameArray();
     foreach ($this->getFileQuery() as $file) {
         // Get the name of the file to import
         $filename = $filenameMap[$file->ID];
         $success = $this->migrateFile($base, $file, $filename);
         if ($success) {
             $count++;
         }
     }
     Versioned::set_reading_mode($originalState);
     return $count;
 }
 public function preRequest(HTTPRequest $request, Session $session, DataModel $model)
 {
     // Bootstrap session so that Session::get() accesses the right instance
     $dummyController = new Controller();
     $dummyController->setSession($session);
     $dummyController->setRequest($request);
     $dummyController->pushCurrent();
     // Block non-authenticated users from setting the stage mode
     if (!Versioned::can_choose_site_stage($request)) {
         $permissionMessage = sprintf(_t("ContentController.DRAFT_SITE_ACCESS_RESTRICTION", 'You must log in with your CMS password in order to view the draft or archived content. ' . '<a href="%s">Click here to go back to the published site.</a>'), Convert::raw2xml(Controller::join_links(Director::baseURL(), $request->getURL(), "?stage=Live")));
         // Force output since RequestFilter::preRequest doesn't support response overriding
         $response = Security::permissionFailure($dummyController, $permissionMessage);
         $session->inst_save();
         $dummyController->popCurrent();
         // Prevent output in testing
         if (class_exists('SilverStripe\\Dev\\SapphireTest', false) && SapphireTest::is_running_test()) {
             throw new HTTPResponse_Exception($response);
         }
         $response->output();
         die;
     }
     Versioned::choose_site_stage();
     $dummyController->popCurrent();
     return true;
 }
 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')));
 }
 public function tearDown()
 {
     AssetStoreTest_SpyStore::reset();
     if ($this->oldReadingMode) {
         Versioned::set_reading_mode($this->oldReadingMode);
     }
     parent::tearDown();
 }
 public function getSchemaStateDefaults()
 {
     $state = parent::getSchemaStateDefaults();
     if ($record = $this->getRecord()) {
         $latest = Versioned::get_latest_version($record->baseClass(), $record->ID);
         if ($latest) {
             $state['data']['fileId'] = $latest->ID;
             $state['data']['latestVersionId'] = $latest->Version;
         }
     }
     return $state;
 }
 /**
  * Test Hierarchy::AllHistoricalChildren().
  */
 public function testAllHistoricalChildren()
 {
     // Delete some objs
     $this->objFromFixture('HierarchyTest_Object', 'obj2b')->delete();
     $this->objFromFixture('HierarchyTest_Object', 'obj3a')->delete();
     $this->objFromFixture('HierarchyTest_Object', 'obj3')->delete();
     // Check that obj1-3 appear at the top level of the AllHistoricalChildren tree
     $this->assertEquals(array("Obj 1", "Obj 2", "Obj 3"), singleton('HierarchyTest_Object')->AllHistoricalChildren()->column('Title'));
     // Check numHistoricalChildren
     $this->assertEquals(3, singleton('HierarchyTest_Object')->numHistoricalChildren());
     // Check that both obj 2 children are returned
     $obj2 = $this->objFromFixture('HierarchyTest_Object', 'obj2');
     $this->assertEquals(array("Obj 2a", "Obj 2b"), $obj2->AllHistoricalChildren()->column('Title'));
     // Check numHistoricalChildren
     $this->assertEquals(2, $obj2->numHistoricalChildren());
     // Obj 3 has been deleted; let's bring it back from the grave
     $obj3 = Versioned::get_including_deleted("HierarchyTest_Object", "\"Title\" = 'Obj 3'")->First();
     // Check that all obj 3 children are returned
     $this->assertEquals(array("Obj 3a", "Obj 3b", "Obj 3c", "Obj 3d"), $obj3->AllHistoricalChildren()->column('Title'));
     // Check numHistoricalChildren
     $this->assertEquals(4, $obj3->numHistoricalChildren());
 }
 protected function init()
 {
     parent::init();
     // Special case for dev/build: Defer permission checks to DatabaseAdmin->init() (see #4957)
     $requestedDevBuild = stripos($this->getRequest()->getURL(), 'dev/build') === 0 && stripos($this->getRequest()->getURL(), 'dev/build/defaults') === false;
     // We allow access to this controller regardless of live-status or ADMIN permission only
     // if on CLI.  Access to this controller is always allowed in "dev-mode", or of the user is ADMIN.
     $canAccess = $requestedDevBuild || Director::isDev() || Director::is_cli() || Permission::check("ADMIN");
     if (!$canAccess) {
         Security::permissionFailure($this);
         return;
     }
     // check for valid url mapping
     // lacking this information can cause really nasty bugs,
     // e.g. when running Director::test() from a FunctionalTest instance
     global $_FILE_TO_URL_MAPPING;
     if (Director::is_cli()) {
         if (isset($_FILE_TO_URL_MAPPING)) {
             $testPath = BASE_PATH;
             $matched = false;
             while ($testPath && $testPath != "/" && !preg_match('/^[A-Z]:\\\\$/', $testPath)) {
                 if (isset($_FILE_TO_URL_MAPPING[$testPath])) {
                     $matched = true;
                     break;
                 }
                 $testPath = dirname($testPath);
             }
             if (!$matched) {
                 echo 'Warning: You probably want to define ' . 'an entry in $_FILE_TO_URL_MAPPING that covers "' . Director::baseFolder() . '"' . "\n";
             }
         } else {
             echo 'Warning: You probably want to define $_FILE_TO_URL_MAPPING in ' . 'your _ss_environment.php as instructed on the "sake" page of the doc.silverstripe.org wiki' . "\n";
         }
     }
     // Backwards compat: Default to "draft" stage, which is important
     // for tasks like dev/build which call DataObject->requireDefaultRecords(),
     // but also for other administrative tasks which have assumptions about the default stage.
     Versioned::set_stage(Versioned::DRAFT);
 }
Exemplo n.º 10
0
 /**
  * Return all the children that this page had, including pages that were deleted from both stage & live.
  *
  * @return DataList
  * @throws Exception
  */
 public function AllHistoricalChildren()
 {
     if (!$this->owner->hasExtension('SilverStripe\\ORM\\Versioning\\Versioned')) {
         throw new Exception('Hierarchy->AllHistoricalChildren() only works with Versioned extension applied');
     }
     $baseTable = $this->owner->baseTable();
     $parentIDColumn = $this->owner->getSchema()->sqlColumnForField($this->owner, 'ParentID');
     return Versioned::get_including_deleted($this->owner->baseClass(), [$parentIDColumn => $this->owner->ID], "\"{$baseTable}\".\"ID\" ASC");
 }
 public function tearDown()
 {
     // Preserve memory settings
     ini_set('memory_limit', $this->originalMemoryLimit ? $this->originalMemoryLimit : -1);
     // Restore email configuration
     $this->originalMailer = null;
     $this->mailer = null;
     // Restore password validation
     if ($this->originalMemberPasswordValidator) {
         Member::set_password_validator($this->originalMemberPasswordValidator);
     }
     // Restore requirements
     if ($this->originalRequirements) {
         Requirements::set_backend($this->originalRequirements);
     }
     // Mark test as no longer being run - we use originalIsRunningTest to allow for nested SapphireTest calls
     self::$is_running_test = $this->originalIsRunningTest;
     $this->originalIsRunningTest = null;
     // Reset mocked datetime
     DBDatetime::clear_mock_now();
     // Stop the redirection that might have been requested in the test.
     // Note: Ideally a clean Controller should be created for each test.
     // Now all tests executed in a batch share the same controller.
     $controller = Controller::has_curr() ? Controller::curr() : null;
     if ($controller && $controller->response && $controller->response->getHeader('Location')) {
         $controller->response->setStatusCode(200);
         $controller->response->removeHeader('Location');
     }
     Versioned::set_reading_mode($this->originalReadingMode);
     //unnest injector / config now that tests are over
     Injector::unnest();
     Config::unnest();
 }
 /**
  * Test files being replaced
  */
 public function testReplaceFile()
 {
     Versioned::set_stage(Versioned::DRAFT);
     /** @var AssetControlExtensionTest_VersionedObject $object1 */
     $object1 = AssetControlExtensionTest_VersionedObject::get()->filter('Title', 'My object')->first();
     /** @var AssetControlExtensionTest_Object $object2 */
     $object2 = AssetControlExtensionTest_Object::get()->filter('Title', 'Unversioned')->first();
     /** @var AssetControlExtensionTest_ArchivedObject $object3 */
     $object3 = AssetControlExtensionTest_ArchivedObject::get()->filter('Title', 'Archived')->first();
     $object1TupleOld = $object1->Header->getValue();
     $object2TupleOld = $object2->Image->getValue();
     $object3TupleOld = $object3->Header->getValue();
     // Replace image and write each to filesystem
     $fish1 = realpath(__DIR__ . '/../model/testimages/test-image-high-quality.jpg');
     $object1->Header->setFromLocalFile($fish1, 'Header/Replaced_MyObjectHeader.jpg');
     $object1->write();
     $object2->Image->setFromLocalFile($fish1, 'Images/Replaced_BeautifulFish.jpg');
     $object2->write();
     $object3->Header->setFromLocalFile($fish1, 'Archived/Replaced_MyObjectHeader.jpg');
     $object3->write();
     // Check that old published records are left public, but removed for unversioned object2
     $this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $this->getAssetStore()->getVisibility($object1TupleOld['Filename'], $object1TupleOld['Hash']));
     $this->assertEquals(null, $this->getAssetStore()->getVisibility($object2TupleOld['Filename'], $object2TupleOld['Hash']));
     $this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $this->getAssetStore()->getVisibility($object3TupleOld['Filename'], $object3TupleOld['Hash']));
     // Check that visibility of new file is correct
     // Note that $object2 has no canView() is true, so assets end up public
     $this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object1->Header->getVisibility());
     $this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object2->Image->getVisibility());
     $this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object3->Header->getVisibility());
     // Publish changes to versioned records
     $object1->publishSingle();
     $object3->publishSingle();
     // After publishing, old object1 is deleted, but since object3 has archiving enabled,
     // the orphaned file is intentionally left in the protected store
     $this->assertEquals(null, $this->getAssetStore()->getVisibility($object1TupleOld['Filename'], $object1TupleOld['Hash']));
     $this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $this->getAssetStore()->getVisibility($object3TupleOld['Filename'], $object3TupleOld['Hash']));
     // And after publish, all files are public
     $this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object1->Header->getVisibility());
     $this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object3->Header->getVisibility());
 }
 /**
  * @uses LeftAndMainExtension->init()
  * @uses LeftAndMainExtension->accessedCMS()
  * @uses CMSMenu
  */
 protected function init()
 {
     parent::init();
     SSViewer::config()->update('rewrite_hash_links', false);
     ContentNegotiator::config()->update('enabled', false);
     // set language
     $member = Member::currentUser();
     if (!empty($member->Locale)) {
         i18n::set_locale($member->Locale);
     }
     if (!empty($member->DateFormat)) {
         i18n::config()->date_format = $member->DateFormat;
     }
     if (!empty($member->TimeFormat)) {
         i18n::config()->time_format = $member->TimeFormat;
     }
     // can't be done in cms/_config.php as locale is not set yet
     CMSMenu::add_link('Help', _t('LeftAndMain.HELP', 'Help', 'Menu title'), $this->config()->help_link, -2, array('target' => '_blank'));
     // Allow customisation of the access check by a extension
     // Also all the canView() check to execute Controller::redirect()
     if (!$this->canView() && !$this->getResponse()->isFinished()) {
         // When access /admin/, we should try a redirect to another part of the admin rather than be locked out
         $menu = $this->MainMenu();
         foreach ($menu as $candidate) {
             if ($candidate->Link && $candidate->Link != $this->Link() && $candidate->MenuItem->controller && singleton($candidate->MenuItem->controller)->canView()) {
                 $this->redirect($candidate->Link);
                 return;
             }
         }
         if (Member::currentUser()) {
             Session::set("BackURL", null);
         }
         // if no alternate menu items have matched, return a permission error
         $messageSet = array('default' => _t('LeftAndMain.PERMDEFAULT', "You must be logged in to access the administration area; please enter your credentials below."), 'alreadyLoggedIn' => _t('LeftAndMain.PERMALREADY', "I'm sorry, but you can't access that part of the CMS.  If you want to log in as someone else, do" . " so below."), 'logInAgain' => _t('LeftAndMain.PERMAGAIN', "You have been logged out of the CMS.  If you would like to log in again, enter a username and" . " password below."));
         Security::permissionFailure($this, $messageSet);
         return;
     }
     // Don't continue if there's already been a redirection request.
     if ($this->redirectedTo()) {
         return;
     }
     // Audit logging hook
     if (empty($_REQUEST['executeForm']) && !$this->getRequest()->isAjax()) {
         $this->extend('accessedCMS');
     }
     // Set the members html editor config
     if (Member::currentUser()) {
         HTMLEditorConfig::set_active_identifier(Member::currentUser()->getHtmlEditorConfigForCMS());
     }
     // Set default values in the config if missing.  These things can't be defined in the config
     // file because insufficient information exists when that is being processed
     $htmlEditorConfig = HTMLEditorConfig::get_active();
     $htmlEditorConfig->setOption('language', i18n::get_tinymce_lang());
     Requirements::customScript("\n\t\t\twindow.ss = window.ss || {};\n\t\t\twindow.ss.config = " . $this->getCombinedClientConfig() . ";\n\t\t");
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/vendor.js');
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/bundle.js');
     Requirements::css(ltrim(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/bundle.css', '/'));
     Requirements::add_i18n_javascript(ltrim(FRAMEWORK_DIR . '/client/lang', '/'), false, true);
     Requirements::add_i18n_javascript(FRAMEWORK_ADMIN_DIR . '/client/lang', false, true);
     if ($this->config()->session_keepalive_ping) {
         Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/LeftAndMain.Ping.js');
     }
     if (Director::isDev()) {
         // TODO Confuses jQuery.ondemand through document.write()
         Requirements::javascript(ADMIN_THIRDPARTY_DIR . '/jquery-entwine/src/jquery.entwine.inspector.js');
         Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/leaktools.js');
     }
     // Custom requirements
     $extraJs = $this->stat('extra_requirements_javascript');
     if ($extraJs) {
         foreach ($extraJs as $file => $config) {
             if (is_numeric($file)) {
                 $file = $config;
             }
             Requirements::javascript($file);
         }
     }
     $extraCss = $this->stat('extra_requirements_css');
     if ($extraCss) {
         foreach ($extraCss as $file => $config) {
             if (is_numeric($file)) {
                 $file = $config;
                 $config = array();
             }
             Requirements::css($file, isset($config['media']) ? $config['media'] : null);
         }
     }
     $extraThemedCss = $this->stat('extra_requirements_themedCss');
     if ($extraThemedCss) {
         foreach ($extraThemedCss as $file => $config) {
             if (is_numeric($file)) {
                 $file = $config;
                 $config = array();
             }
             Requirements::themedCSS($file, isset($config['media']) ? $config['media'] : null);
         }
     }
     $dummy = null;
     $this->extend('init', $dummy);
     // Assign default cms theme and replace user-specified themes
     SSViewer::set_themes($this->config()->admin_themes);
     //set the reading mode for the admin to stage
     Versioned::set_stage(Versioned::DRAFT);
 }
 public function testLazyLoadedFieldsDoNotReferenceVersionsTable()
 {
     // Save another record, sanity check that we're getting the right one
     $obj2 = new VersionedTest_Subclass();
     $obj2->Name = "test2";
     $obj2->ExtraField = "foo2";
     $obj2->write();
     $obj1 = new VersionedLazySub_DataObject();
     $obj1->PageName = "old-value";
     $obj1->ExtraField = "old-value";
     $obj1ID = $obj1->write();
     $obj1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
     $obj1 = VersionedLazySub_DataObject::get()->byID($obj1ID);
     $this->assertEquals('old-value', $obj1->PageName, "Correct value on base table when fetching base class");
     $this->assertEquals('old-value', $obj1->ExtraField, "Correct value on sub table when fetching base class");
     $obj1 = VersionedLazy_DataObject::get()->byID($obj1ID);
     $this->assertEquals('old-value', $obj1->PageName, "Correct value on base table when fetching sub class");
     $this->assertEquals('old-value', $obj1->ExtraField, "Correct value on sub table when fetching sub class");
     // Force inconsistent state to test behaviour (shouldn't select from *_versions)
     DB::query(sprintf("UPDATE \"VersionedLazy_DataObject_versions\" SET \"PageName\" = 'versioned-value' " . "WHERE \"RecordID\" = %d", $obj1ID));
     DB::query(sprintf("UPDATE \"VersionedLazySub_DataObject_versions\" SET \"ExtraField\" = 'versioned-value' " . "WHERE \"RecordID\" = %d", $obj1ID));
     $obj1 = VersionedLazySub_DataObject::get()->byID($obj1ID);
     $this->assertEquals('old-value', $obj1->PageName, "Correct value on base table when fetching base class");
     $this->assertEquals('old-value', $obj1->ExtraField, "Correct value on sub table when fetching base class");
     $obj1 = VersionedLazy_DataObject::get()->byID($obj1ID);
     $this->assertEquals('old-value', $obj1->PageName, "Correct value on base table when fetching sub class");
     $this->assertEquals('old-value', $obj1->ExtraField, "Correct value on sub table when fetching sub class");
     // Update live table only to test behaviour (shouldn't select from *_versions or stage)
     DB::query(sprintf('UPDATE "VersionedLazy_DataObject_Live" SET "PageName" = \'live-value\' WHERE "ID" = %d', $obj1ID));
     DB::query(sprintf('UPDATE "VersionedLazySub_DataObject_Live" SET "ExtraField" = \'live-value\' WHERE "ID" = %d', $obj1ID));
     Versioned::set_stage(Versioned::LIVE);
     $obj1 = VersionedLazy_DataObject::get()->byID($obj1ID);
     $this->assertEquals('live-value', $obj1->PageName, "Correct value from base table when fetching base class on live stage");
     $this->assertEquals('live-value', $obj1->ExtraField, "Correct value from sub table when fetching base class on live stage");
 }
 /**
  * Values that are overwritten with null are saved to the _versions table correctly.
  */
 public function testWriteNullValueToVersion()
 {
     $record = VersionedTest_Subclass::create();
     $record->Title = "Test A";
     $record->write();
     $version = Versioned::get_latest_version($record->ClassName, $record->ID);
     $this->assertEquals(1, $version->Version);
     $this->assertEquals($record->Title, $version->Title);
     $record->Title = null;
     $record->write();
     $version = Versioned::get_latest_version($record->ClassName, $record->ID);
     $this->assertEquals(2, $version->Version);
     $this->assertEquals($record->Title, $version->Title);
 }
 /**
  * Ensure that related objects are disassociated on live
  */
 public function testUnlinkDisassociated()
 {
     $this->publishAllFixtures();
     /** @var ChangeSetTest_Base $base */
     $base = $this->objFromFixture(ChangeSetTest_Base::class, 'base');
     /** @var ChangeSetTest_Mid $mid1 $mid2 */
     $mid1 = $this->objFromFixture(ChangeSetTest_Mid::class, 'mid1');
     $mid2 = $this->objFromFixture(ChangeSetTest_Mid::class, 'mid2');
     // Remove mid1 from stage
     $this->assertEquals($base->ID, $mid1->BaseID);
     $this->assertEquals($base->ID, $mid2->BaseID);
     $mid1->deleteFromStage(Versioned::DRAFT);
     // Publishing recursively should unlinkd this object
     $changeset = new ChangeSet();
     $changeset->write();
     $changeset->addObject($base);
     // Assert changeset only contains root object
     $this->assertChangeSetLooksLike($changeset, ['ChangeSetTest_Base.base' => ChangeSetItem::EXPLICITLY]);
     $changeset->publish();
     // mid1 on live exists, but has BaseID set to zero
     $mid1Live = Versioned::get_by_stage(ChangeSetTest_Mid::class, Versioned::LIVE)->byID($mid1->ID);
     $this->assertNotNull($mid1Live);
     $this->assertEquals($mid1->ID, $mid1Live->ID);
     $this->assertEquals(0, $mid1Live->BaseID);
     // mid2 on live exists and retains BaseID
     $mid2Live = Versioned::get_by_stage(ChangeSetTest_Mid::class, Versioned::LIVE)->byID($mid2->ID);
     $this->assertNotNull($mid2Live);
     $this->assertEquals($mid2->ID, $mid2Live->ID);
     $this->assertEquals($base->ID, $mid2Live->BaseID);
 }
 /**
  * Tests for the bug #5994 - Moving folder after executing Folder::findOrMake will not set the Filenames properly
  */
 public function testFindOrMakeFolderThenMove()
 {
     $folder1 = $this->objFromFixture('SilverStripe\\Assets\\Folder', 'folder1');
     Folder::find_or_make($folder1->Filename);
     $folder2 = $this->objFromFixture('SilverStripe\\Assets\\Folder', 'folder2');
     // Publish file1
     /** @var File $file1 */
     $file1 = DataObject::get_by_id('SilverStripe\\Assets\\File', $this->idFromFixture('SilverStripe\\Assets\\File', 'file1-folder1'), false);
     $file1->publishRecursive();
     // set ParentID. This should cause updateFilesystem to be called on all children
     $folder1->ParentID = $folder2->ID;
     $folder1->write();
     // Check if the file in the folder moved along
     /** @var File $file1Draft */
     $file1Draft = Versioned::get_by_stage('SilverStripe\\Assets\\File', Versioned::DRAFT)->byID($file1->ID);
     $this->assertFileExists(AssetStoreTest_SpyStore::getLocalPath($file1Draft));
     $this->assertEquals('FileTest-folder2/FileTest-folder1/File1.txt', $file1Draft->Filename, 'The file DataObject has updated path');
     // File should be located in new folder
     $this->assertEquals(ASSETS_PATH . '/FolderTest/.protected/FileTest-folder2/FileTest-folder1/55b443b601/File1.txt', AssetStoreTest_SpyStore::getLocalPath($file1Draft));
     // Published (live) version remains in the old location
     /** @var File $file1Live */
     $file1Live = Versioned::get_by_stage('SilverStripe\\Assets\\File', Versioned::LIVE)->byID($file1->ID);
     $this->assertEquals(ASSETS_PATH . '/FolderTest/FileTest-folder1/55b443b601/File1.txt', AssetStoreTest_SpyStore::getLocalPath($file1Live));
     // Publishing the draft to live should move the new file to the public store
     $file1Draft->publishRecursive();
     $this->assertEquals(ASSETS_PATH . '/FolderTest/FileTest-folder2/FileTest-folder1/55b443b601/File1.txt', AssetStoreTest_SpyStore::getLocalPath($file1Draft));
 }
 /**
  * Check if this ChangeSetItem can be published
  *
  * @param Member $member
  * @return bool
  */
 public function canPublish($member = null)
 {
     // Check canMethod to invoke on object
     switch ($this->getChangeType()) {
         case static::CHANGE_DELETED:
             /** @var Versioned|DataObject $object */
             $object = Versioned::get_by_stage($this->ObjectClass, Versioned::LIVE)->byID($this->ObjectID);
             if (!$object || !$object->canUnpublish($member)) {
                 return false;
             }
             break;
         default:
             /** @var Versioned|DataObject $object */
             $object = Versioned::get_by_stage($this->ObjectClass, Versioned::DRAFT)->byID($this->ObjectID);
             if (!$object || !$object->canPublish($member)) {
                 return false;
             }
             break;
     }
     // If object can be published/unpublished let extensions deny
     return $this->can(__FUNCTION__, $member);
 }
Exemplo n.º 19
0
 /**
  * Update filesystem of all children
  */
 public function updateChildFilesystem()
 {
     // Don't synchronise on live (rely on publishing instead)
     if (Versioned::get_stage() === Versioned::LIVE) {
         return;
     }
     $this->flushCache();
     // Writing this record should trigger a write (and potential updateFilesystem) on each child
     foreach ($this->AllChildren() as $child) {
         $child->write();
     }
 }
 /**
  * Check if this ChangeSetItem can be published
  *
  * @param Member $member
  * @return bool
  */
 public function canPublish($member = null)
 {
     // Check canMethod to invoke on object
     switch ($this->getChangeType()) {
         case static::CHANGE_DELETED:
             /** @var Versioned|DataObject $object */
             $object = Versioned::get_by_stage($this->ObjectClass, Versioned::LIVE)->byID($this->ObjectID);
             if ($object) {
                 return $object->canUnpublish($member);
             }
             break;
         default:
             /** @var Versioned|DataObject $object */
             $object = Versioned::get_by_stage($this->ObjectClass, Versioned::DRAFT)->byID($this->ObjectID);
             if ($object) {
                 return $object->canPublish($member);
             }
             break;
     }
     return false;
 }
 /**
  * @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);
 }
 /**
  * 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;
 }
 public function testPublishing()
 {
     /** @var ManyManyThroughListTest_VersionedObject $draftParent */
     $draftParent = $this->objFromFixture(ManyManyThroughListTest_VersionedObject::class, 'parent1');
     $draftParent->publishRecursive();
     // Modify draft stage
     $item1 = $draftParent->Items()->filter(['Title' => 'versioned item 1'])->first();
     $item1->Title = 'new versioned item 1';
     $item1->getJoin()->Title = 'new versioned join 1';
     $item1->write(false, false, false, true);
     // Write joined components
     $draftParent->Title = 'new versioned title';
     $draftParent->write();
     // Check owned objects on stage
     $draftOwnedObjects = $draftParent->findOwned(true);
     $this->assertDOSEquals([['Title' => 'new versioned join 1'], ['Title' => 'versioned join 2'], ['Title' => 'new versioned item 1'], ['Title' => 'versioned item 2']], $draftOwnedObjects);
     // Check live record is still old values
     // This tests that both the join table and many_many tables
     // inherit the necessary query parameters from the parent object.
     /** @var ManyManyThroughListTest_VersionedObject $liveParent */
     $liveParent = Versioned::get_by_stage(ManyManyThroughListTest_VersionedObject::class, Versioned::LIVE)->byID($draftParent->ID);
     $liveOwnedObjects = $liveParent->findOwned(true);
     $this->assertDOSEquals([['Title' => 'versioned join 1'], ['Title' => 'versioned join 2'], ['Title' => 'versioned item 1'], ['Title' => 'versioned item 2']], $liveOwnedObjects);
     // Publish draft changes
     $draftParent->publishRecursive();
     $liveParent = Versioned::get_by_stage(ManyManyThroughListTest_VersionedObject::class, Versioned::LIVE)->byID($draftParent->ID);
     $liveOwnedObjects = $liveParent->findOwned(true);
     $this->assertDOSEquals([['Title' => 'new versioned join 1'], ['Title' => 'versioned join 2'], ['Title' => 'new versioned item 1'], ['Title' => 'versioned item 2']], $liveOwnedObjects);
 }
Exemplo n.º 24
0
 /**
  * Test a URL request, returning a response object. This method is the counterpart of
  * Director::direct() that is used in functional testing. It will execute the URL given, and
  * return the result as an SS_HTTPResponse object.
  *
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Handles the page logic for a Director::direct() call.
  *
  * @param string $url The URL to visit.
  * @param array $postVars The $_POST & $_FILES variables.
  * @param array|Session $session The {@link Session} object representing the current session.
  * By passing the same object to multiple  calls of Director::test(), you can simulate a persisted
  * session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if
  * postVars is set, GET otherwise. Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body.
  * @param array $headers HTTP headers with key-value pairs.
  * @param array|Cookie_Backend $cookies to populate $_COOKIE.
  * @param HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request.
  *
  * @return SS_HTTPResponse
  *
  * @throws SS_HTTPResponse_Exception
  */
 public static function test($url, $postVars = null, $session = array(), $httpMethod = null, $body = null, $headers = array(), $cookies = array(), &$request = null)
 {
     Config::nest();
     Injector::nest();
     // These are needed so that calling Director::test() does not muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics.
     $oldReadingMode = Versioned::get_reading_mode();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = Injector::inst()->create('Session', array());
     }
     $cookieJar = $cookies instanceof Cookie_Backend ? $cookies : Injector::inst()->createWithArgs('Cookie_Backend', array($cookies ?: array()));
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingRequirementsBackend = Requirements::backend();
     Config::inst()->update('Cookie', 'report_errors', false);
     Requirements::set_backend(Injector::inst()->create('Requirements_Backend'));
     // Set callback to invoke prior to return
     $onCleanup = function () use($existingRequestVars, $existingGetVars, $existingPostVars, $existingSessionVars, $existingCookies, $existingServer, $existingRequirementsBackend, $oldReadingMode) {
         // Restore the super globals
         $_REQUEST = $existingRequestVars;
         $_GET = $existingGetVars;
         $_POST = $existingPostVars;
         $_SESSION = $existingSessionVars;
         $_COOKIE = $existingCookies;
         $_SERVER = $existingServer;
         Requirements::set_backend($existingRequirementsBackend);
         // These are needed so that calling Director::test() does not muck with whoever is calling it.
         // Really, it's some inappropriate coupling and should be resolved by making less use of statics
         Versioned::set_reading_mode($oldReadingMode);
         Injector::unnest();
         // Restore old CookieJar, etc
         Config::unnest();
     };
     if (strpos($url, '#') !== false) {
         $url = substr($url, 0, strpos($url, '#'));
     }
     // Handle absolute URLs
     if (parse_url($url, PHP_URL_HOST)) {
         $bits = parse_url($url);
         // If a port is mentioned in the absolute URL, be sure to add that into the HTTP host
         if (isset($bits['port'])) {
             $_SERVER['HTTP_HOST'] = $bits['host'] . ':' . $bits['port'];
         } else {
             $_SERVER['HTTP_HOST'] = $bits['host'];
         }
     }
     // Ensure URL is properly made relative.
     // Example: url passed is "/ss31/my-page" (prefixed with BASE_URL), this should be changed to "my-page"
     $url = self::makeRelative($url);
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the super globals with appropriate test values
     $_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = $cookieJar->getAll(false);
     Injector::inst()->registerService($cookieJar, 'Cookie_Backend');
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $request = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $request->addHeader($k, $v);
         }
     }
     // Pre-request filtering
     // @see issue #2517
     $model = DataModel::inst();
     $output = Injector::inst()->get('RequestProcessor')->preRequest($request, $session, $model);
     if ($output === false) {
         $onCleanup();
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     // TODO: Pass in the DataModel
     $result = Director::handleRequest($request, $session, $model);
     // Ensure that the result is an SS_HTTPResponse object
     if (is_string($result)) {
         if (substr($result, 0, 9) == 'redirect:') {
             $response = new SS_HTTPResponse();
             $response->redirect(substr($result, 9));
             $result = $response;
         } else {
             $result = new SS_HTTPResponse($result);
         }
     }
     $output = Injector::inst()->get('RequestProcessor')->postRequest($request, $result, $model);
     if ($output === false) {
         $onCleanup();
         throw new SS_HTTPResponse_Exception("Invalid response");
     }
     // Return valid response
     $onCleanup();
     return $result;
 }
 /**
  * Test that rolling back to a single version works recursively
  */
 public function testRecursiveRollback()
 {
     /** @var VersionedOwnershipTest_Subclass $subclass2 */
     $this->sleep(1);
     $subclass2 = $this->objFromFixture('VersionedOwnershipTest_Subclass', 'subclass2_published');
     // Create a few new versions
     $versions = [];
     for ($version = 1; $version <= 3; $version++) {
         // Write owned objects
         $this->sleep(1);
         foreach ($subclass2->findOwned(true) as $obj) {
             $obj->Title .= " - v{$version}";
             $obj->write();
         }
         // Write parent
         $this->sleep(1);
         $subclass2->Title .= " - v{$version}";
         $subclass2->write();
         $versions[$version] = $subclass2->Version;
     }
     // Check reverting to first version
     $this->sleep(1);
     $subclass2->doRollbackTo($versions[1]);
     /** @var VersionedOwnershipTest_Subclass $subclass2Draft */
     $subclass2Draft = Versioned::get_by_stage('VersionedOwnershipTest_Subclass', Versioned::DRAFT)->byID($subclass2->ID);
     $this->assertEquals('Subclass 2 - v1', $subclass2Draft->Title);
     $this->assertDOSEquals([['Title' => 'Related 2 - v1'], ['Title' => 'Attachment 3 - v1'], ['Title' => 'Attachment 4 - v1'], ['Title' => 'Attachment 5 - v1'], ['Title' => 'Related Many 4 - v1']], $subclass2Draft->findOwned(true));
     // Check rolling forward to a later version
     $this->sleep(1);
     $subclass2->doRollbackTo($versions[3]);
     /** @var VersionedOwnershipTest_Subclass $subclass2Draft */
     $subclass2Draft = Versioned::get_by_stage('VersionedOwnershipTest_Subclass', Versioned::DRAFT)->byID($subclass2->ID);
     $this->assertEquals('Subclass 2 - v1 - v2 - v3', $subclass2Draft->Title);
     $this->assertDOSEquals([['Title' => 'Related 2 - v1 - v2 - v3'], ['Title' => 'Attachment 3 - v1 - v2 - v3'], ['Title' => 'Attachment 4 - v1 - v2 - v3'], ['Title' => 'Attachment 5 - v1 - v2 - v3'], ['Title' => 'Related Many 4 - v1 - v2 - v3']], $subclass2Draft->findOwned(true));
     // And rolling back one version
     $this->sleep(1);
     $subclass2->doRollbackTo($versions[2]);
     /** @var VersionedOwnershipTest_Subclass $subclass2Draft */
     $subclass2Draft = Versioned::get_by_stage('VersionedOwnershipTest_Subclass', Versioned::DRAFT)->byID($subclass2->ID);
     $this->assertEquals('Subclass 2 - v1 - v2', $subclass2Draft->Title);
     $this->assertDOSEquals([['Title' => 'Related 2 - v1 - v2'], ['Title' => 'Attachment 3 - v1 - v2'], ['Title' => 'Attachment 4 - v1 - v2'], ['Title' => 'Attachment 5 - v1 - v2'], ['Title' => 'Related Many 4 - v1 - v2']], $subclass2Draft->findOwned(true));
 }
 public function testPublish()
 {
     $this->publishAllFixtures();
     $base = $this->objFromFixture('ChangeSetTest_Base', 'base');
     $baseID = $base->ID;
     $baseBefore = $base->Version;
     $end1 = $this->objFromFixture('ChangeSetTest_End', 'end1');
     $end1ID = $end1->ID;
     $end1Before = $end1->Version;
     // Create a new changest
     $changeset = new ChangeSet();
     $changeset->write();
     $changeset->addObject($base);
     $changeset->addObject($end1);
     // Make a lot of changes
     // - ChangeSetTest_Base.base modified
     // - ChangeSetTest_End.end1 deleted
     // - new ChangeSetTest_Mid added
     $base->Foo = 343;
     $base->write();
     $baseAfter = $base->Version;
     $midNew = new ChangeSetTest_Mid();
     $midNew->Bar = 39;
     $midNew->write();
     $midNewID = $midNew->ID;
     $midNewAfter = $midNew->Version;
     $end1->delete();
     $changeset->addObject($midNew);
     // Publish
     $this->logInWithPermission('ADMIN');
     $this->assertTrue($changeset->canPublish());
     $this->assertTrue($changeset->isSynced());
     $changeset->publish();
     $this->assertEquals(ChangeSet::STATE_PUBLISHED, $changeset->State);
     // Check each item has the correct before/after version applied
     $baseChange = $changeset->Changes()->filter(['ObjectClass' => 'ChangeSetTest_Base', 'ObjectID' => $baseID])->first();
     $this->assertEquals((int) $baseBefore, (int) $baseChange->VersionBefore);
     $this->assertEquals((int) $baseAfter, (int) $baseChange->VersionAfter);
     $this->assertEquals((int) $baseChange->VersionBefore + 1, (int) $baseChange->VersionAfter);
     $this->assertEquals((int) $baseChange->VersionAfter, (int) Versioned::get_versionnumber_by_stage('ChangeSetTest_Base', Versioned::LIVE, $baseID));
     $end1Change = $changeset->Changes()->filter(['ObjectClass' => 'ChangeSetTest_End', 'ObjectID' => $end1ID])->first();
     $this->assertEquals((int) $end1Before, (int) $end1Change->VersionBefore);
     $this->assertEquals(0, (int) $end1Change->VersionAfter);
     $this->assertEquals(0, (int) Versioned::get_versionnumber_by_stage('ChangeSetTest_End', Versioned::LIVE, $end1ID));
     $midNewChange = $changeset->Changes()->filter(['ObjectClass' => 'ChangeSetTest_Mid', 'ObjectID' => $midNewID])->first();
     $this->assertEquals(0, (int) $midNewChange->VersionBefore);
     $this->assertEquals((int) $midNewAfter, (int) $midNewChange->VersionAfter);
     $this->assertEquals((int) $midNewAfter, (int) Versioned::get_versionnumber_by_stage('ChangeSetTest_Mid', Versioned::LIVE, $midNewID));
     // Test trying to re-publish is blocked
     $this->setExpectedException('BadMethodCallException', "ChangeSet can't be published if it has been already published or reverted.");
     $changeset->publish();
 }
 /**
  * Checks all stages other than the current stage, and check the visibility
  * of assets attached to those records.
  *
  * @param AssetManipulationList $manipulation Set of manipulations to add assets to
  */
 protected function addAssetsFromOtherStages(AssetManipulationList $manipulation)
 {
     // Skip unversioned or unsaved assets
     if (!$this->isVersioned() || !$this->owner->isInDB()) {
         return;
     }
     // Unauthenticated member to use for checking visibility
     $baseClass = $this->owner->baseClass();
     $baseTable = $this->owner->baseTable();
     $filter = array("\"{$baseTable}\".\"ID\"" => $this->owner->ID);
     $stages = $this->owner->getVersionedStages();
     // {@see Versioned::getVersionedStages}
     foreach ($stages as $stage) {
         // Skip current stage; These should be handled explicitly
         if ($stage === Versioned::get_stage()) {
             continue;
         }
         // Check if record exists in this stage
         $record = Versioned::get_one_by_stage($baseClass, $stage, $filter);
         if (!$record) {
             continue;
         }
         // Check visibility of this record, and record all attached assets
         $state = $this->getRecordState($record);
         $this->addAssetsFromRecord($manipulation, $record, $state);
     }
 }
Exemplo n.º 28
0
 /**
  * This will check if the parent record and/or name do not match the name on the underlying
  * DBFile record, and if so, copy this file to the new location, and update the record to
  * point to this new file.
  *
  * This method will update the File {@see DBFile} field value on success, so it must be called
  * before writing to the database
  *
  * @return bool True if changed
  */
 public function updateFilesystem()
 {
     if (!$this->config()->update_filesystem) {
         return false;
     }
     // Check the file exists
     if (!$this->File->exists()) {
         return false;
     }
     // Avoid moving files on live; Rely on this being done on stage prior to publish.
     if (Versioned::get_stage() !== Versioned::DRAFT) {
         return false;
     }
     // Check path updated record will point to
     // If no changes necessary, skip
     $pathBefore = $this->File->getFilename();
     $pathAfter = $this->generateFilename();
     if ($pathAfter === $pathBefore) {
         return false;
     }
     // Copy record to new location via stream
     $stream = $this->File->getStream();
     $this->File->setFromStream($stream, $pathAfter);
     return true;
 }
 /**
  * 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;
 }
Exemplo n.º 30
0
 public function setUp()
 {
     parent::setUp();
     Versioned::set_stage(Versioned::DRAFT);
     AssetStoreTest_SpyStore::activate('UploadTest');
 }