public function tearDown()
 {
     parent::tearDown();
     i18n::set_locale($this->originalLocale);
     Config::inst()->remove('SilverStripe\\Forms\\TimeField', 'default_config');
     Config::inst()->update('SilverStripe\\Forms\\TimeField', 'default_config', $this->origTimeConfig);
 }
 public function testReadonly()
 {
     i18n::set_locale('en_US');
     $field = new NumericField('Number');
     $this->assertRegExp("#<span[^>]+>\\s*0\\s*<\\/span>#", "" . $field->performReadonlyTransformation()->Field() . "");
 }
 /**
  * @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()
 {
     //nest config and injector for each test so they are effectively sandboxed per test
     Config::nest();
     Injector::nest();
     $this->originalReadingMode = Versioned::get_reading_mode();
     // We cannot run the tests on this abstract class.
     if (get_class($this) == __CLASS__) {
         $this->markTestSkipped(sprintf('Skipping %s ', get_class($this)));
         return;
     }
     // Mark test as being run
     $this->originalIsRunningTest = self::$is_running_test;
     self::$is_running_test = true;
     // i18n needs to be set to the defaults or tests fail
     i18n::set_locale(i18n::config()->get('default_locale'));
     i18n::config()->date_format = null;
     i18n::config()->time_format = null;
     // Set default timezone consistently to avoid NZ-specific dependencies
     date_default_timezone_set('UTC');
     // Remove password validation
     $this->originalMemberPasswordValidator = Member::password_validator();
     $this->originalRequirements = Requirements::backend();
     Member::set_password_validator(null);
     Cookie::config()->update('report_errors', false);
     if (class_exists('SilverStripe\\CMS\\Controllers\\RootURLController')) {
         RootURLController::reset();
     }
     if (class_exists('Translatable')) {
         Translatable::reset();
     }
     Versioned::reset();
     DataObject::reset();
     if (class_exists('SilverStripe\\CMS\\Model\\SiteTree')) {
         SiteTree::reset();
     }
     Hierarchy::reset();
     if (Controller::has_curr()) {
         Controller::curr()->setSession(Session::create(array()));
     }
     Security::$database_is_ready = null;
     // Add controller-name auto-routing
     // @todo Fix to work with namespaced controllers
     Director::config()->update('rules', array('$Controller//$Action/$ID/$OtherID' => '*'));
     $fixtureFiles = $this->getFixturePaths();
     // Todo: this could be a special test model
     $this->model = DataModel::inst();
     // Set up fixture
     if ($fixtureFiles || $this->usesDatabase) {
         if (!self::using_temp_db()) {
             self::create_temp_db();
         }
         DataObject::singleton()->flushCache();
         self::empty_temp_db();
         foreach ($this->requireDefaultRecordsFrom as $className) {
             $instance = singleton($className);
             if (method_exists($instance, 'requireDefaultRecords')) {
                 $instance->requireDefaultRecords();
             }
             if (method_exists($instance, 'augmentDefaultRecords')) {
                 $instance->augmentDefaultRecords();
             }
         }
         foreach ($fixtureFiles as $fixtureFilePath) {
             $fixture = YamlFixture::create($fixtureFilePath);
             $fixture->writeInto($this->getFixtureFactory());
         }
         $this->logInWithPermission("ADMIN");
     }
     // Preserve memory settings
     $this->originalMemoryLimit = ini_get('memory_limit');
     // turn off template debugging
     SSViewer::config()->update('source_file_comments', false);
     // Clear requirements
     Requirements::clear();
     // Set up email
     $this->mailer = new TestMailer();
     Injector::inst()->registerService($this->mailer, 'SilverStripe\\Control\\Email\\Mailer');
     Email::config()->remove('send_all_emails_to');
 }
 /**
  * Write a Money object to the database, then re-read it to ensure it
  * is re-read properly.
  */
 public function testGettingWrittenDataObject()
 {
     $local = i18n::get_locale();
     //make sure that the $ amount is not prefixed by US$, as it would be in non-US locale
     i18n::set_locale('en_US');
     $obj = new MoneyTest_DataObject();
     $m = new DBMoney();
     $m->setAmount(987.65);
     $m->setCurrency('USD');
     $obj->MyMoney = $m;
     $this->assertEquals("\$987.65", $obj->MyMoney->Nice(), "Money field not added to data object properly when read prior to first writing the record.");
     $objID = $obj->write();
     $moneyTest = DataObject::get_by_id('MoneyTest_DataObject', $objID);
     $this->assertTrue($moneyTest instanceof MoneyTest_DataObject);
     $this->assertEquals('USD', $moneyTest->MyMoneyCurrency);
     $this->assertEquals(987.65, $moneyTest->MyMoneyAmount);
     $this->assertEquals("\$987.65", $moneyTest->MyMoney->Nice(), "Money field not added to data object properly when read.");
     i18n::set_locale($local);
 }
 public function testRepeatedLoginAttemptsLockingPeopleOut()
 {
     $local = i18n::get_locale();
     i18n::set_locale('en_US');
     Member::config()->lock_out_after_incorrect_logins = 5;
     Member::config()->lock_out_delay_mins = 15;
     // Login with a wrong password for more than the defined threshold
     for ($i = 1; $i <= Member::config()->lock_out_after_incorrect_logins + 1; $i++) {
         $this->doTestLoginForm('*****@*****.**', 'incorrectpassword');
         $member = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'test'));
         if ($i < Member::config()->lock_out_after_incorrect_logins) {
             $this->assertNull($member->LockedOutUntil, 'User does not have a lockout time set if under threshold for failed attempts');
             $this->assertContains($this->loginErrorMessage(), Convert::raw2xml(_t('Member.ERRORWRONGCRED')));
         } else {
             // Fuzzy matching for time to avoid side effects from slow running tests
             $this->assertGreaterThan(time() + 14 * 60, strtotime($member->LockedOutUntil), 'User has a lockout time set after too many failed attempts');
         }
         $msg = _t('Member.ERRORLOCKEDOUT2', 'Your account has been temporarily disabled because of too many failed attempts at ' . 'logging in. Please try again in {count} minutes.', null, array('count' => Member::config()->lock_out_delay_mins));
         if ($i > Member::config()->lock_out_after_incorrect_logins) {
             $this->assertContains($msg, $this->loginErrorMessage());
         }
     }
     $this->doTestLoginForm('*****@*****.**', '1nitialPassword');
     $this->assertNull($this->session()->inst_get('loggedInAs'), 'The user can\'t log in after being locked out, even with the right password');
     // (We fake this by re-setting LockedOutUntil)
     $member = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'test'));
     $member->LockedOutUntil = date('Y-m-d H:i:s', time() - 30);
     $member->write();
     $this->doTestLoginForm('*****@*****.**', '1nitialPassword');
     $this->assertEquals($this->session()->inst_get('loggedInAs'), $member->ID, 'After lockout expires, the user can login again');
     // Log the user out
     $this->session()->inst_set('loggedInAs', null);
     // Login again with wrong password, but less attempts than threshold
     for ($i = 1; $i < Member::config()->lock_out_after_incorrect_logins; $i++) {
         $this->doTestLoginForm('*****@*****.**', 'incorrectpassword');
     }
     $this->assertNull($this->session()->inst_get('loggedInAs'));
     $this->assertContains($this->loginErrorMessage(), Convert::raw2xml(_t('Member.ERRORWRONGCRED')), 'The user can retry with a wrong password after the lockout expires');
     $this->doTestLoginForm('*****@*****.**', '1nitialPassword');
     $this->assertEquals($this->session()->inst_get('loggedInAs'), $member->ID, 'The user can login successfully after lockout expires, if staying below the threshold');
     i18n::set_locale($local);
 }
 public function testCollectFromFilesystemAndWriteMasterTables()
 {
     $local = i18n::get_locale();
     i18n::set_locale('en_US');
     //set the locale to the US locale expected in the asserts
     i18n::config()->update('default_locale', 'en_US');
     $c = new i18nTextCollector();
     $c->setWriter(new i18nTextCollector_Writer_RailsYaml());
     $c->basePath = $this->alternateBasePath;
     $c->baseSavePath = $this->alternateBaseSavePath;
     $c->run();
     // i18ntestmodule
     $moduleLangFile = "{$this->alternateBaseSavePath}/i18ntestmodule/lang/" . $c->getDefaultLocale() . '.yml';
     $this->assertTrue(file_exists($moduleLangFile), 'Master language file can be written to modules /lang folder');
     $moduleLangFileContent = file_get_contents($moduleLangFile);
     $this->assertContains("    ADDITION: Addition\n", $moduleLangFileContent);
     $this->assertContains("    ENTITY: 'Entity with \"Double Quotes\"'\n", $moduleLangFileContent);
     $this->assertContains("    MAINTEMPLATE: 'Main Template'\n", $moduleLangFileContent);
     $this->assertContains("    OTHERENTITY: 'Other Entity'\n", $moduleLangFileContent);
     $this->assertContains("    WITHNAMESPACE: 'Include Entity with Namespace'\n", $moduleLangFileContent);
     $this->assertContains("    NONAMESPACE: 'Include Entity without Namespace'\n", $moduleLangFileContent);
     // i18nothermodule
     $otherModuleLangFile = "{$this->alternateBaseSavePath}/i18nothermodule/lang/" . $c->getDefaultLocale() . '.yml';
     $this->assertTrue(file_exists($otherModuleLangFile), 'Master language file can be written to modules /lang folder');
     $otherModuleLangFileContent = file_get_contents($otherModuleLangFile);
     $this->assertContains("    ENTITY: 'Other Module Entity'\n", $otherModuleLangFileContent);
     $this->assertContains("    MAINTEMPLATE: 'Main Template Other Module'\n", $otherModuleLangFileContent);
     // testtheme1
     $theme1LangFile = "{$this->alternateBaseSavePath}/themes/testtheme1/lang/" . $c->getDefaultLocale() . '.yml';
     $this->assertTrue(file_exists($theme1LangFile), 'Master theme language file can be written to themes/testtheme1 /lang folder');
     $theme1LangFileContent = file_get_contents($theme1LangFile);
     $this->assertContains("    MAINTEMPLATE: 'Theme1 Main Template'\n", $theme1LangFileContent);
     $this->assertContains("    LAYOUTTEMPLATE: 'Theme1 Layout Template'\n", $theme1LangFileContent);
     $this->assertContains("    SPRINTFNAMESPACE: 'Theme1 My replacement: %s'\n", $theme1LangFileContent);
     $this->assertContains("    LAYOUTTEMPLATENONAMESPACE: 'Theme1 Layout Template no namespace'\n", $theme1LangFileContent);
     $this->assertContains("    SPRINTFNONAMESPACE: 'Theme1 My replacement no namespace: %s'\n", $theme1LangFileContent);
     $this->assertContains("    SPRINTFINCLUDENAMESPACE: 'Theme1 My include replacement: %s'\n", $theme1LangFileContent);
     $this->assertContains("    WITHNAMESPACE: 'Theme1 Include Entity with Namespace'\n", $theme1LangFileContent);
     $this->assertContains("    NONAMESPACE: 'Theme1 Include Entity without Namespace'\n", $theme1LangFileContent);
     $this->assertContains("    SPRINTFINCLUDENONAMESPACE: 'Theme1 My include replacement no namespace: %s'\n", $theme1LangFileContent);
     // testtheme2
     $theme2LangFile = "{$this->alternateBaseSavePath}/themes/testtheme2/lang/" . $c->getDefaultLocale() . '.yml';
     $this->assertTrue(file_exists($theme2LangFile), 'Master theme language file can be written to themes/testtheme2 /lang folder');
     $theme2LangFileContent = file_get_contents($theme2LangFile);
     $this->assertContains("    MAINTEMPLATE: 'Theme2 Main Template'\n", $theme2LangFileContent);
     i18n::set_locale($local);
     //set the locale to the US locale expected in the asserts
 }