public function setUp()
 {
     parent::setUp();
     $this->logInWithPermission('ADMIN');
     // Save versioned state
     $this->oldReadingMode = Versioned::get_reading_mode();
     Versioned::set_stage(Versioned::DRAFT);
     // Set backend root to /UploadFieldTest
     AssetStoreTest_SpyStore::activate('UploadFieldTest');
     // Set the File Name Filter replacements so files have the expected names
     Config::inst()->update('SilverStripe\\Assets\\FileNameFilter', 'default_replacements', array('/\\s/' => '-', '/_/' => '-', '/[^A-Za-z0-9+.\\-]+/' => '', '/[\\-]{2,}/' => '-', '/^[\\.\\-_]+/' => ''));
     // Create a test folders for each of the fixture references
     foreach (Folder::get() as $folder) {
         $path = AssetStoreTest_SpyStore::getLocalPath($folder);
         Filesystem::makeFolder($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);
         Filesystem::makeFolder(dirname($path));
         $fh = fopen($path, "w+");
         fwrite($fh, str_repeat('x', 1000000));
         fclose($fh);
     }
 }
 /**
  * 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 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);
     }
 }
 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');
     }
 }
 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);
             }
         }
     }
 }
 public function setUp()
 {
     parent::setUp();
     Versioned::set_stage(Versioned::DRAFT);
     // Set backend root to /DataDifferencerTest
     AssetStoreTest_SpyStore::activate('DataDifferencerTest');
     // Create a test files for each of the fixture references
     $files = File::get()->exclude('ClassName', 'Folder');
     foreach ($files as $file) {
         $fromPath = BASE_PATH . '/framework/tests/model/testimages/' . $file->Name;
         $destPath = AssetStoreTest_SpyStore::getLocalPath($file);
         // Only correct for test asset store
         SS_Filesystem::makeFolder(dirname($destPath));
         copy($fromPath, $destPath);
     }
 }
 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);
 }
 /**
  * @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 setUp()
 {
     parent::setUp();
     Versioned::set_stage(Versioned::DRAFT);
     AssetStoreTest_SpyStore::activate('UploadTest');
 }
 public function testCanViewStage()
 {
     $public = $this->objFromFixture('VersionedTest_PublicStage', 'public1');
     $private = $this->objFromFixture('VersionedTest_DataObject', 'page1');
     Session::clear("loggedInAs");
     Versioned::set_stage(Versioned::DRAFT);
     // Test that all (and only) public pages are viewable in stage mode
     // Unpublished records are not viewable in live regardless of permissions
     $this->assertTrue($public->canViewStage('Stage'));
     $this->assertFalse($private->canViewStage('Stage'));
     $this->assertFalse($public->canViewStage('Live'));
     $this->assertFalse($private->canViewStage('Live'));
     // Writing records to live should make both stage and live modes viewable
     $private->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
     $public->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
     $this->assertTrue($public->canViewStage('Stage'));
     $this->assertTrue($private->canViewStage('Stage'));
     $this->assertTrue($public->canViewStage('Live'));
     $this->assertTrue($private->canViewStage('Live'));
     // If the draft mode changes, the live mode remains public, although the updated
     // draft mode is secured for non-public records.
     $private->Title = 'Secret Title';
     $private->write();
     $public->Title = 'Public Title';
     $public->write();
     $this->assertTrue($public->canViewStage('Stage'));
     $this->assertFalse($private->canViewStage('Stage'));
     $this->assertTrue($public->canViewStage('Live'));
     $this->assertTrue($private->canViewStage('Live'));
 }
 /**
  * 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());
 }
 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");
 }
 /**
  * Write the given record to the draft stage
  *
  * @param string $stage
  * @param boolean $forceInsert
  * @return int The ID of the record
  */
 public function writeToStage($stage, $forceInsert = false)
 {
     $oldMode = Versioned::get_reading_mode();
     Versioned::set_stage($stage);
     $owner = $this->owner;
     $owner->forceChange();
     $result = $owner->write(false, $forceInsert);
     Versioned::set_reading_mode($oldMode);
     return $result;
 }
 public function testVersionedCache()
 {
     $origReadingMode = Versioned::get_reading_mode();
     // Run without caching in stage to prove data is uncached
     $this->_reset(false);
     Versioned::set_stage(Versioned::DRAFT);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('default');
     $this->assertEquals('default Stage.Stage', SSViewer::execute_string('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('first Stage.Stage', SSViewer::execute_string('<% cached %>$Inspect<% end_cached %>', $data));
     // Run without caching in live to prove data is uncached
     $this->_reset(false);
     Versioned::set_stage(Versioned::LIVE);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('default');
     $this->assertEquals('default Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('first Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     // Then with caching, initially in draft, and then in live, to prove that
     // changing the versioned reading mode doesn't cache between modes, but it does
     // within them
     $this->_reset(true);
     Versioned::set_stage(Versioned::DRAFT);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('default');
     $this->assertEquals('default Stage.Stage', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('default Stage.Stage', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     Versioned::set_stage(Versioned::LIVE);
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('first');
     $this->assertEquals('first Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     $data = new SSViewerCacheBlockTest_VersionedModel();
     $data->setEntropy('second');
     $this->assertEquals('first Stage.Live', $this->_runtemplate('<% cached %>$Inspect<% end_cached %>', $data));
     Versioned::set_reading_mode($origReadingMode);
 }