public function EnvironmentType() { if (Director::isLive()) { return "live"; } else { if (Director::isTest()) { return "test"; } else { return "dev"; } } }
/** * Create a response with the given error code * * @param int $code * @return HTTPResponse */ protected function createErrorResponse($code) { $response = new HTTPResponse('', $code); // Show message in dev if (!Director::isLive()) { $response->setBody($response->getStatusDescription()); } return $response; }
global $manifest; $manifest = new ClassManifest(BASE_PATH, false, $flush); // Register SilverStripe's class map autoload $loader = ClassLoader::instance(); $loader->registerAutoloader(); $loader->pushManifest($manifest); // Now that the class manifest is up, load the static configuration $configManifest = new ConfigStaticManifest(); Config::inst()->pushConfigStaticManifest($configManifest); // And then the yaml configuration $configManifest = new ConfigManifest(BASE_PATH, false, $flush); Config::inst()->pushConfigYamlManifest($configManifest); // Load template manifest SilverStripe\View\ThemeResourceLoader::instance()->addSet('$default', new SilverStripe\View\ThemeManifest(BASE_PATH, project(), false, $flush)); // If in live mode, ensure deprecation, strict and notices are not reported if (Director::isLive()) { error_reporting(E_ALL & ~(E_DEPRECATED | E_STRICT | E_NOTICE)); } /////////////////////////////////////////////////////////////////////////////// // POST-MANIFEST COMMANDS /** * Load error handlers */ $errorHandler = Injector::inst()->get('ErrorHandler'); $errorHandler->start(); /////////////////////////////////////////////////////////////////////////////// // HELPER FUNCTIONS /** * Creates a class instance by the "singleton" design pattern. * It will always return the same instance for this class, * which can be used for performance reasons and as a simple
/** * Show a debugging message * * @param string $message * @param bool $showHeader */ public static function message($message, $showHeader = true) { if (!Director::isLive()) { $caller = Debug::caller(); $file = basename($caller['file']); if (Director::is_cli()) { if ($showHeader) { echo "Debug (line {$caller['line']} of {$file}):\n "; } echo $message . "\n"; } else { echo "<p class=\"message warning\">\n"; if ($showHeader) { echo "<b>Debug (line {$caller['line']} of {$file}):</b>\n "; } echo Convert::raw2xml($message) . "</p>\n"; } } }
/** * Can also be checked with {@link Director::isDev()}, {@link Director::isTest()}, and * {@link Director::isLive()}. * * @return bool|string */ public static function get_environment_type() { if (Director::isLive()) { return 'live'; } elseif (Director::isTest()) { return 'test'; } elseif (Director::isDev()) { return 'dev'; } else { return false; } }
/** * Send this HTTPReponse to the browser */ public function output() { // Attach appropriate X-Include-JavaScript and X-Include-CSS headers if (Director::is_ajax()) { Requirements::include_in_response($this); } if (in_array($this->statusCode, self::$redirect_codes) && headers_sent($file, $line)) { $url = Director::absoluteURL($this->headers['Location'], true); $urlATT = Convert::raw2htmlatt($url); $urlJS = Convert::raw2js($url); $title = Director::isDev() ? "{$urlATT}... (output started on {$file}, line {$line})" : "{$urlATT}..."; echo <<<EOT <p>Redirecting to <a href="{$urlATT}" title="Click this link if your browser does not redirect you">{$title}</a></p> <meta http-equiv="refresh" content="1; url={$urlATT}" /> <script type="application/javascript">setTimeout(function(){ \twindow.location.href = "{$urlJS}"; }, 50);</script> EOT; } else { $line = $file = null; if (!headers_sent($file, $line)) { header($_SERVER['SERVER_PROTOCOL'] . " {$this->statusCode} " . $this->getStatusDescription()); foreach ($this->headers as $header => $value) { //etags need to be quoted if (strcasecmp('etag', $header) === 0 && 0 !== strpos($value, '"')) { $value = sprintf('"%s"', $value); } header("{$header}: {$value}", true, $this->statusCode); } } else { // It's critical that these status codes are sent; we need to report a failure if not. if ($this->statusCode >= 300) { user_error("Couldn't set response type to {$this->statusCode} because " . "of output on line {$line} of {$file}", E_USER_WARNING); } } // Only show error pages or generic "friendly" errors if the status code signifies // an error, and the response doesn't have any body yet that might contain // a more specific error description. if (Director::isLive() && $this->isError() && !$this->body) { $formatter = Injector::inst()->get('FriendlyErrorFormatter'); echo $formatter->format(array('code' => $this->statusCode)); } else { echo $this->body; } } }
/** * Event handler called before writing to the database. */ public function onBeforeWrite() { if ($this->SetPassword) { $this->Password = $this->SetPassword; } // If a member with the same "unique identifier" already exists with a different ID, don't allow merging. // Note: This does not a full replacement for safeguards in the controller layer (e.g. in a registration form), // but rather a last line of defense against data inconsistencies. $identifierField = Member::config()->unique_identifier_field; if ($this->{$identifierField}) { // Note: Same logic as Member_Validator class $filter = array("\"{$identifierField}\"" => $this->{$identifierField}); if ($this->ID) { $filter[] = array('"Member"."ID" <> ?' => $this->ID); } $existingRecord = DataObject::get_one('SilverStripe\\Security\\Member', $filter); if ($existingRecord) { throw new ValidationException(ValidationResult::create(false, _t('Member.ValidationIdentifierFailed', 'Can\'t overwrite existing member #{id} with identical identifier ({name} = {value}))', 'Values in brackets show "fieldname = value", usually denoting an existing email address', array('id' => $existingRecord->ID, 'name' => $identifierField, 'value' => $this->{$identifierField})))); } } // We don't send emails out on dev/tests sites to prevent accidentally spamming users. // However, if TestMailer is in use this isn't a risk. if ((Director::isLive() || Email::mailer() instanceof TestMailer) && $this->isChanged('Password') && $this->record['Password'] && $this->config()->notify_password_change) { /** @var Email $e */ $e = Email::create(); $e->setSubject(_t('Member.SUBJECTPASSWORDCHANGED', "Your password has been changed", 'Email subject')); $e->setTemplate('ChangePasswordEmail'); $e->populateTemplate($this); $e->setTo($this->Email); $e->send(); } // The test on $this->ID is used for when records are initially created. // Note that this only works with cleartext passwords, as we can't rehash // existing passwords. if (!$this->ID && $this->Password || $this->isChanged('Password')) { //reset salt so that it gets regenerated - this will invalidate any persistant login cookies // or other information encrypted with this Member's settings (see self::encryptWithUserSettings) $this->Salt = ''; // Password was changed: encrypt the password according the settings $encryption_details = Security::encrypt_password($this->Password, $this->Salt, $this->PasswordEncryption ? $this->PasswordEncryption : Security::config()->password_encryption_algorithm, $this); // Overwrite the Password property with the hashed value $this->Password = $encryption_details['password']; $this->Salt = $encryption_details['salt']; $this->PasswordEncryption = $encryption_details['algorithm']; // If we haven't manually set a password expiry if (!$this->isChanged('PasswordExpiry')) { // then set it for us if (self::config()->password_expiry_days) { $this->PasswordExpiry = date('Y-m-d', time() + 86400 * self::config()->password_expiry_days); } else { $this->PasswordExpiry = null; } } } // save locale if (!$this->Locale) { $this->Locale = i18n::get_locale(); } parent::onBeforeWrite(); }
/** * Returns false if the non-prefilterable parts of the rule aren't met, and true if they are * * @param array $rules * @return bool|string */ public function matchesVariantRules($rules) { $matches = "undefined"; // Needs to be truthy, but not true foreach ($rules as $k => $v) { switch (strtolower($k)) { case 'classexists': case 'moduleexists': break; case 'environment': switch (strtolower($v)) { case 'live': $matches = $matches && Director::isLive(); break; case 'test': $matches = $matches && Director::isTest(); break; case 'dev': $matches = $matches && Director::isDev(); break; default: user_error('Unknown environment ' . $v . ' in config fragment', E_USER_ERROR); } break; case 'envvarset': $matches = $matches && isset($_ENV[$v]); break; case 'constantdefined': $matches = $matches && defined($v); break; default: $matches = $matches && (isset($_ENV[$k]) && $_ENV[$k] == $v || defined($k) && constant($k) == $v); break; } if ($matches === false) { return $matches; } } return $matches; }
/** * Determines if the name is valid, as a security * measure against setting arbitrary databases. * * @param String $name * @return Boolean */ public static function valid_alternative_database_name($name) { if (Director::isLive()) { return false; } $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; $pattern = strtolower(sprintf('/^%stmpdb\\d{7}$/', $prefix)); return (bool) preg_match($pattern, $name); }
/** * Tests isDev, isTest, isLive set from querystring */ public function testQueryIsEnvironment() { // Reset unset($_SESSION['isDev']); unset($_SESSION['isLive']); unset($_GET['isTest']); unset($_GET['isDev']); $_SESSION = $_SESSION ?: array(); // Test isDev=1 $_GET['isDev'] = '1'; $this->assertTrue(Director::isDev()); $this->assertFalse(Director::isTest()); $this->assertFalse(Director::isLive()); // Test persistence unset($_GET['isDev']); $this->assertTrue(Director::isDev()); $this->assertFalse(Director::isTest()); $this->assertFalse(Director::isLive()); // Test change to isTest $_GET['isTest'] = '1'; $this->assertFalse(Director::isDev()); $this->assertTrue(Director::isTest()); $this->assertFalse(Director::isLive()); // Test persistence unset($_GET['isTest']); $this->assertFalse(Director::isDev()); $this->assertTrue(Director::isTest()); $this->assertFalse(Director::isLive()); }
/** * Given a request, and an action name, call that action name on this RequestHandler * * Must not raise HTTPResponse_Exceptions - instead it should return * * @param $request * @param $action * @return HTTPResponse */ protected function handleAction($request, $action) { $classMessage = Director::isLive() ? 'on this handler' : 'on class ' . get_class($this); if (!$this->hasMethod($action)) { return new HTTPResponse("Action '{$action}' isn't available {$classMessage}.", 404); } $res = $this->extend('beforeCallActionHandler', $request, $action); if ($res) { return reset($res); } $actionRes = $this->{$action}($request); $res = $this->extend('afterCallActionHandler', $request, $action, $actionRes); if ($res) { return reset($res); } return $actionRes; }