Merge pull request #6337 from dhensby/pulls/4/dotenv

NEW replace _ss_environment.php with .env and environment vars
This commit is contained in:
Damian Mooyman 2017-02-01 13:09:10 +13:00 committed by GitHub
commit b4536bf36e
40 changed files with 427 additions and 522 deletions

View File

@ -20,6 +20,21 @@ if(PHP_SAPI != "cli" && PHP_SAPI != "cgi" && PHP_SAPI != "cgi-fcgi") {
die();
}
// We update the $_SERVER variable to contain data consistent with the rest of the application.
$_SERVER = array_merge(array(
'SERVER_PROTOCOL' => 'HTTP/1.1',
'HTTP_ACCEPT' => 'text/plain;q=0.5',
'HTTP_ACCEPT_LANGUAGE' => '*;q=0.5',
'HTTP_ACCEPT_ENCODING' => '',
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1;q=0.5',
'SERVER_SIGNATURE' => 'Command-line PHP/' . phpversion(),
'SERVER_SOFTWARE' => 'PHP/' . phpversion(),
'SERVER_ADDR' => '127.0.0.1',
'REMOTE_ADDR' => '127.0.0.1',
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => 'CLI',
), $_SERVER);
/**
* Identify the cli-script.php file and change to its container directory, so that require_once() works
*/
@ -82,23 +97,20 @@ $_SESSION = null;
// Connect to database
if(!isset($databaseConfig) || !isset($databaseConfig['database']) || !$databaseConfig['database']) {
echo "\nPlease configure your database connection details. You can do this by creating a file
called _ss_environment.php in either of the following locations:\n\n";
echo " - " . BASE_PATH . DIRECTORY_SEPARATOR . "_ss_environment.php\n - ";
echo dirname(BASE_PATH) . DIRECTORY_SEPARATOR . "_ss_environment.php\n\n";
called .env in " . BASE_PATH;
echo <<<ENVCONTENT
Put the following content into this file:
--------------------------------------------------
<?php
/* Change this from 'dev' to 'live' for a production environment. */
define('SS_ENVIRONMENT_TYPE', 'dev');
# Change this from 'dev' to 'live' for a production environment.
SS_ENVIRONMENT_TYPE="dev"
/* This defines a default database user */
define('SS_DATABASE_SERVER', 'localhost');
define('SS_DATABASE_USERNAME', '<user>');
define('SS_DATABASE_PASSWORD', '<password>');
define('SS_DATABASE_NAME', '<database>');
SS_DATABASE_SERVER="localhost"
SS_DATABASE_USERNAME="<user>"
SS_DATABASE_PASSWORD="<password>"
SS_DATABASE_NAME="<database>"
--------------------------------------------------
Once you have done that, run 'composer install' or './framework/sake dev/build' to create

View File

@ -24,7 +24,8 @@
"embed/embed": "^2.6",
"swiftmailer/swiftmailer": "~5.4",
"symfony/config": "^2.8|^3",
"symfony/translation": "^2.8|^3"
"symfony/translation": "^2.8|^3",
"vlucas/phpdotenv": "^2.4"
},
"require-dev": {
"phpunit/PHPUnit": "~4.8",

View File

@ -38,7 +38,7 @@ $ composer create-project silverstripe/installer ./silverstripe
* Rename the unpacked directory from `C:\wamp\www\silverstripe-vX.X.X` to `C:\wamp\www\silverstripe`
## Install and configure
* Option 1: Environment file - Set up a file named _ss_environment.php either in the webroot or a directory above webroot and setup as per the [Environment Management process](/getting_started/environment_management).
* Option 1: Environment file - Set up a file named `.env` file either in the webroot and setup as per the [Environment Management process](/getting_started/environment_management).
* Option 2: Installer - Visit `http://localhost/silverstripe` - you will see SilverStripe's installation screen.
* You should be able to click "Install SilverStripe" and the installer will do its thing. It takes a minute or two.

View File

@ -160,22 +160,21 @@ You will need to give **Modify** permission to **IUSR** user. To do it right cli
Now that we've got the backend server software sorted out, it's time to install the SilverStripe CMS/framework.
Create a new file called **_ss_environment.php** in **C:\inetpub\wwwroot**
Create a new file called `.env` in **C:\inetpub\wwwroot\ss**
This file tells SilverStripe projects installed on this machine which database server and credentials, as well as anything environment specific.
Inside the newly created _ss_environment.php file, insert the following code:
Inside the newly created `.env` file, insert the following code:
<?php
/* What kind of environment is this: development, test, or live (ie, production)? */
define('SS_ENVIRONMENT_TYPE', 'dev');
/* Database connection */
define('SS_DATABASE_SERVER', 'localhost');
define('SS_DATABASE_USERNAME', 'sa');
define('SS_DATABASE_PASSWORD', '');
/* Configure a default username and password to access the CMS on all sites in this environment */
define('SS_DEFAULT_ADMIN_USERNAME', 'username');
define('SS_DEFAULT_ADMIN_PASSWORD', 'password');
# What kind of environment is this: development, test, or live (ie, production)?
SS_ENVIRONMENT_TYPE="dev";
# Database connection
SS_DATABASE_SERVER="localhost"
SS_DATABASE_USERNAME="sa"
SS_DATABASE_PASSWORD=""
# Configure a default username and password to access the CMS on all sites in this environment
SS_DEFAULT_ADMIN_USERNAME="username"
SS_DEFAULT_ADMIN_PASSWORD="password"
Insert the password you created for SQL Server earlier into the **SS_DATABASE_PASSWORD** field that is currently empty.
@ -211,7 +210,7 @@ If all goes to plan, you're done, and you should see a basic template with a few
Most of the time, it's caused by a loaded PHP extension that is broken.
* Have you set up the MSSQL database details correctly in _ss_environment.php?
* Have you set up the MSSQL database details correctly in `.env` file?
* Have you made IIS expose errors? (see "How do I make IIS expose errors..." below)
* Are you running non-standard PHP extensions? If so, try unloading them one by one
* Make sure you're using the latest [[http://www.microsoft.com/downloads/en/details.aspx?FamilyID=80E44913-24B4-4113-8807-CAAE6CF2CA05&displaylang=en/|Microsoft Drivers for PHP for SQL Server]]

View File

@ -129,20 +129,18 @@ Since SilverStripe modules are installed into their own folder, you have to mana
Here is the default SilverStripe [.gitignore](http://git-scm.com/docs/gitignore) with the forum module ignored
```
assets/*
_ss_environment.php
tools/phing-metadata
silverstripe-cache
.buildpath
.project
.settings
.idea
.DS_Store
vendor/
# Don't include the forum module, as this will be installed with composer
forum
```
```assets/*
.env
tools/phing-metadata
silverstripe-cache
.buildpath
.project
.settings
.idea
.DS_Store
vendor/
# Don't include the forum module, as this will be installed with composer
forum```
In large projects it can get difficult to manage your [.gitignore](http://git-scm.com/docs/gitignore) and ensure it contains all composer managed modules and themes.

View File

@ -1,112 +1,65 @@
# Environment management
As website developers, we noticed that we had a few problems. You may have the same problems:
As part of website development and hosting it is natural for our sites to be hosted on several different environments.
These can be our laptops for local development, a testing server for customers to test changes on, or a production
server.
* On our development laptops, we have a number of sites, but the database connection details are the same for each of
them. Why should we have to go through the installation process and re-enter them each time?
* Each of those sites needed to be in development mode when we were editing them on our laptops, but in production mode
when we deploy them to our servers. Additionally, our production host's database connection details will likely be
different than our local server.
For each of these environments we may require slightly different configurations for our servers. This could be our debug
level, caching backends, or - of course - sensitive information such as database credentials.
SilverStripe comes with a solution to this: the `_ss_environment.php` file. You can put a single `_ss_environment.php`
file in your "projects" folder on your development box, and it will be used by each of your development sites.
To solve this problem of setting variables per environment we use environment variables with the help of the
[PHPDotEnv](https://github.com/vlucas/phpdotenv) library by Vance Lucas.
## Setting up your development machine with _ss_environment.php
## Security considerations
In this example, we assume that you are managing multiple projects as subfolders of `~/Sites/`, and that you can visit
these at `http://localhost/`. For example, you might have a project at `~/Sites/myproject/`, and visit it at
`http://localhost/myproject/`.
Sensitive credentials should not be stored in a VCS or project code and should only be stored on the environment in
question. When using live environments the use of `.env` files is discouraged and instead one should use "first class"
environment variables.
Create a new file, `~/Sites/_ss_environment.php`. Put the following content in it, editing the values of the
"SS_DATABASE_..." and "SS_DEFAULT_ADMIN_..." defines as appropriate.
If you do use a `.env` file on your servers, you must ensure that external access to `.env` files is blocked by the
webserver.
:::php
<?php
/* What kind of environment is this: development, test, or live (ie, production)? */
define('SS_ENVIRONMENT_TYPE', 'dev/test/live');
/* Database connection */
define('SS_DATABASE_SERVER', 'localhost');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '');
/* Configure a default username and password to access the CMS on all sites in this environment. */
define('SS_DEFAULT_ADMIN_USERNAME', 'username');
define('SS_DEFAULT_ADMIN_PASSWORD', 'password');
## Managing environment variables with `.env` files
By default the `.env` must be placed in your project root (ie: same folder as you `composer.json`) or the parent
directory. If this file exists, it will be automatically loaded by the framework and the environment variables will be
set. An example `.env` file is included in the default installer named`.env.example`.
Now, edit each of your site's configuration file, usually `mysite/_config.php`. Delete all mention
of `$databaseConfig` and `Director::set_dev_servers`, and instead make sure that you file starts like this.
## Managing environment variables with Apache
:::php
<?php
global $project;
$project = 'mysite';
global $database;
$database = '(databasename)';
// Use _ss_environment.php file for configuration
require_once("conf/ConfigureFromEnv.php");
You can set "real" environment variables using Apache. Please
[see the Apache docs for more information](https://httpd.apache.org/docs/current/env.html)
## How to access the environment variables
## How it works
Accessing the environment varaibles is easy and can be done using the `getenv` method or in the `$_ENV` and `$_SERVER`
super-globals:
The mechanism by which the `_ss_environment.php` files work is quite simple. Here's how it works:
```php
getenv('SS_DATABASE_CLASS');
$_ENV['SS_DATABASE_CLASS'];
$_SERVER['SS_DATABASE_CLASS'];
```
* At the beginning of SilverStripe's execution, the `_ss_environment.php` file is searched for, and if it is found, it's
included. SilverStripe looks in all the parent folders of framework up to the server root (using the REAL location of
the dir - see PHP realpath()):
* The `_ss_environment.php` file sets a number of "define()".
* "conf/ConfigureFromEnv.php" is included from within your `mysite/_config.php`. This file has a number of regular
configuration commands that use those defines as their arguments. If you are curious, open up
`framework/conf/ConfigureFromEnv.php` and see for yourself!
## Including an extra `.env` file
### An Example
Sometimes it may be useful to include an extra `.env` file - on a shared local development environment where all
database credentials could be the same. To do this, you can add this snippet to your `mysite/_config.php` file:
This is my `_ss_environment.php` file. I have it placed in `/var`, as each of the sites are in a subfolder of `/var`.
```php
try {
(new \Dotenv\Dotenv('/path/to/env/'))->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
// no file found
}
```
:::php
<?php
// These four define set the database connection details.
define('SS_DATABASE_CLASS', 'MySQLPDODatabase');
define('SS_DATABASE_SERVER', 'localhost');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '<password>');
// This sets a prefix, which is prepended to the $database variable. This is
// helpful mainly on shared hosts, when every database has a prefix.
define('SS_DATABASE_PREFIX', 'simon_');
// These two lines are a bit complicated. If I'm connecting to the server from
// 127.0.0.1 or MyIP and I'm using a browser with a + in the UserAgent, the site
// is put in dev mode, otherwise it is put in live mode. Most sites would only
// need to put the site in either dev or live mode, thus wont need the IP checks
if(isset($_SERVER['REMOTE_ADDR']) && ($_SERVER['REMOTE_ADDR'] == '127.0.0.1' || ($_SERVER['REMOTE_ADDR'] == '<MyIP>'
&& strpos($_SERVER['HTTP_USER_AGENT'], '+') !== false)))
define('SS_ENVIRONMENT_TYPE', 'dev');
else
define('SS_ENVIRONMENT_TYPE', 'live');
// These two defines sets a default login which, when used, will always log
// you in as an admin, even creating one if none exist.
define('SS_DEFAULT_ADMIN_USERNAME', '<email>');
define('SS_DEFAULT_ADMIN_PASSWORD', '<password>');
// This causes errors to be written to the BASE_PATH/silverstripe.log file.
// Path must be relative to BASE_PATH
define('SS_ERROR_LOG', 'silverstripe.log');
// This is used by sake to know which directory points to which URL
global $_FILE_TO_URL_MAPPING;
$_FILE_TO_URL_MAPPING['/var/www'] = 'http://simon.geek.nz';
## Core environment variables
## Available Constants
SilverStripe core environment variables are listed here, though you're free to define any you need for your application.
| Name | Description |
| ---- | ----------- |
| `TEMP_FOLDER` | Absolute file path to store temporary files such as cached templates or the class manifest. Needs to be writeable by the webserver user. Defaults to *silverstripe-cache* in the webroot, and falls back to *sys_get_temp_dir()*. See *getTempFolder()* in *framework/core/TempPath.php*.|
| `SS_DATABASE_CLASS` | The database class to use, MySQLPDODatabase, MySQLDatabase, MSSQLDatabase, etc. defaults to MySQLDatabase.|
| `SS_DATABASE_SERVER`| The database server to use, defaulting to localhost.|
| `SS_DATABASE_USERNAME`| The database username (mandatory).|
@ -125,3 +78,13 @@ This is my `_ss_environment.php` file. I have it placed in `/var`, as each of th
| `SS_SEND_ALL_EMAILS_TO`| If you define this constant, all emails will be redirected to this address.|
| `SS_SEND_ALL_EMAILS_FROM`| If you define this constant, all emails will be sent from this address.|
| `SS_ERROR_LOG` | Relative path to the log file. |
| `SS_PROTECTED_ASSETS_PATH` | Path to secured assets - defaults to ASSET_PATH/.protected |
| `SS_DATABASE_MEMORY` | Used for SQLite3 DBs |
| `SS_TRUSTED_PROXY_PROTOCOL_HEADER` | Used to define the proxy header to be used to determine HTTPS status |
| `SS_TRUSTED_PROXY_IP_HEADER` | Used to define the proxy header to be used to determine request IPs |
| `SS_TRUSTED_PROXY_HOST_HEADER` | Used to define the proxy header to be used to determine the requested host name |
| `SS_TRUSTED_PROXY_IPS` | IP address or CIDR range to trust proxy headers from |
| `SS_ALLOWED_HOSTS` | A comma deliminated list of hostnames the site is allowed to respond to |
| `SS_MANIFESTCACHE` | The manifest cache to use (defaults to file based caching) |
| `SS_IGNORE_DOT_ENV` | If set the .env file will be ignored. This is good for live to mitigate any performance implications of loading the .env file |
| `SS_HOST` | The hostname to use when it isn't determinable by other means (eg: for CLI commands) |

View File

@ -4,11 +4,10 @@ summary: Site configuration variables such as database connection details, envir
# Environment Variables
Environment specific variables like database connection details, API keys and other server configuration should be kept
outside the application code in a separate `_ss_environment.php` file. This file is stored outside the web root and
version control for security reasons.
outside the application code in a separate `.env` file. This file is stored in the web root and
kept out of version control for security reasons.
For more information on the environment file, see the [Environment Management](../../getting_started/environment_management/)
documentation.
For more information see our docs on [Environment Management](../../getting_started/environment_management/).
Data which isn't sensitive that can be in version control but is mostly static such as constants is best suited to be
included through the [Configuration API](configuration) based on the standard environment types (dev / test / live).
included through the [Configuration API](configuration) based on the standard environment types (dev / test / live).

View File

@ -13,10 +13,9 @@ The definition of setting an environment type in a `mysite/_config/app.yml` look
SilverStripe\Control\Director:
environment_type: 'dev'
The definition of setting an environment type in a `_ss_environment.php` file looks like
The definition of setting an environment type in a `.env` file looks like
:::php
define('SS_ENVIRONMENT_TYPE', 'dev');
SS_ENVIRONMENT_TYPE="dev"
The three environment types you can set are `dev`, `test` and `live`.

View File

@ -37,13 +37,12 @@ When a new SilverStripe site is created for the first time, it may be necessary
CMS access for the first time. SilverStripe provides a default admin configuration system, which allows a username
and password to be configured for a single special user outside of the normal membership system.
It is advisable to configure this user in your `_ss_environment.php` file outside of the web root, as below:
It is advisable to configure this user in your `.env` file inside of the web root, as below:
:::php
// Configure a default username and password to access the CMS on all sites in this environment.
define('SS_DEFAULT_ADMIN_USERNAME', 'admin');
define('SS_DEFAULT_ADMIN_PASSWORD', 'password');
# Configure a default username and password to access the CMS on all sites in this environment.
SS_DEFAULT_ADMIN_USERNAME="admin"
SS_DEFAULT_ADMIN_PASSWORD="password"
When a user logs in with these credentials, then a [api:Member] with the Email 'admin' will be generated in
the database, but without any password information. This means that the password can be reset or changed by simply
updating the `_ss_environment.php` file.
updating the `.env` file.

View File

@ -537,11 +537,10 @@ as well as the login form.
To prevent a forged hostname appearing being used by the application, SilverStripe
allows the configure of a whitelist of hosts that are allowed to access the system. By defining
this whitelist in your _ss_environment.php file, any request presenting a `Host` header that is
this whitelist in your `.env` file, any request presenting a `Host` header that is
_not_ in this list will be blocked with a HTTP 400 error:
:::php
define('SS_ALLOWED_HOSTS', 'www.mysite.com,mysite.com,subdomain.mysite.com');
SS_ALLOWED_HOSTS="www.mysite.com,mysite.com,subdomain.mysite.com"
Please note that if this configuration is defined, you _must_ include _all_ subdomains (eg www.)
that will be accessing the site.
@ -556,14 +555,12 @@ mechanisms, as rewritten urls could persist between requests in order to misdire
into visiting external sites.
In order to prevent this kind of attack, it's necessary to whitelist trusted proxy
server IPs using the SS_TRUSTED_PROXY_IPS define in your _ss_environment.php.
server IPs using the SS_TRUSTED_PROXY_IPS define in your `.env`.
:::php
define('SS_TRUSTED_PROXY_IPS', '127.0.0.1,192.168.0.1');
define('SS_TRUSTED_PROXY_HOST_HEADER', 'HTTP_X_FORWARDED_HOST');
define('SS_TRUSTED_PROXY_IP_HEADER', 'HTTP_X_FORWARDED_FOR');
define('SS_TRUSTED_PROXY_PROTOCOL_HEADER', 'HTTP_X_FORWARDED_PROTOCOL');
SS_TRUSTED_PROXY_IPS="127.0.0.1,192.168.0.1"
SS_TRUSTED_PROXY_HOST_HEADER="HTTP_X_FORWARDED_HOST"
SS_TRUSTED_PROXY_IP_HEADER="HTTP_X_FORWARDED_FOR"
SS_TRUSTED_PROXY_PROTOCOL_HEADER="HTTP_X_FORWARDED_PROTOCOL"
At the same time, you'll also need to define which headers you trust from these proxy IPs. Since there are multiple ways through which proxies can pass through HTTP information on the original hostname, IP and protocol, these values need to be adjusted for your specific proxy. The header names match their equivalent `$_SERVER` values.
@ -571,14 +568,14 @@ If there is no proxy server, 'none' can be used to distrust all clients.
If only trusted servers will make requests then you can use '*' to trust all clients.
Otherwise a comma separated list of individual IP addresses should be declared.
This behaviour is enabled whenever SS_TRUSTED_PROXY_IPS is defined, or if the
This behaviour is enabled whenever `SS_TRUSTED_PROXY_IPS` is defined, or if the
`BlockUntrustedIPs` environment variable is declared. It is advisable to include the
following in your .htaccess to ensure this behaviour is activated.
<IfModule mod_env.c>
# Ensure that X-Forwarded-Host is only allowed to determine the request
# hostname for servers ips defined by SS_TRUSTED_PROXY_IPS in your _ss_environment.php
# hostname for servers ips defined by SS_TRUSTED_PROXY_IPS in your .env
# Note that in a future release this setting will be always on.
SetEnv BlockUntrustedIPs true
</IfModule>
@ -586,7 +583,7 @@ following in your .htaccess to ensure this behaviour is activated.
In a future release this behaviour will be changed to be on by default, and this environment
variable will be no longer necessary, thus it will be necessary to always set
SS_TRUSTED_PROXY_IPS if using a proxy.
`SS_TRUSTED_PROXY_IPS` if using a proxy.
## Related

View File

@ -232,11 +232,10 @@ In order to better ensure these files are protected, it's recommended to move th
root altogether.
For instance, given your web root is in the folder `/sites/mysite/www`, you can tell the asset store
to put protected files into `/sites/mysite/protected` with the below `_ss_environment.php` setting:
to put protected files into `/sites/mysite/protected` with the below `.env` setting:
:::php
define('SS_PROTECTED_ASSETS_PATH', '/sites/mysite/protected');
SS_PROTECTED_ASSETS_PATH="/sites/mysite/protected"
### Configuring: File types

View File

@ -15,7 +15,7 @@ By default, manifests are stored on the local filesystem through PHP's `serializ
Combined with PHP opcode caching this provides fast access.
In order to share manifests between servers, or centralise cache management,
other storage adapters are available. These can be configured by a `SS_MANIFESTCACHE` constant,
placed in your `_ss_environment.php`.
placed in your `.env`.
* `ManifestCache_File`: The default adapter using PHP's `serialize()`
* `ManifestCache_File_PHP`: Using `var_export()`, which is faster when a PHP opcode cache is installed

View File

@ -80,13 +80,12 @@ can leave sensitive files exposed to public access (the `RewriteRule` conditions
All requests go through `framework/main.php`, which sets up the execution environment:
* Tries to locate an `_ss_environment.php`
[configuration file](/getting_started/environment_management) in the webroot,
or the two levels above it (to allow sharing configuration between multiple webroots).
* Tries to locate an `.env`
[configuration file](/getting_started/environment_management) in the webroot.
* Sets constants based on the filesystem structure (e.g. `BASE_URL`, `BASE_PATH` and `TEMP_FOLDER`)
* Normalizes the `url` parameter in preparation for handing it off to `Director`
* Connects to a database, based on information stored in the global `$databaseConfig` variable.
The configuration is either defined in your `_config.php`, or through `_ss_environment.php`
The configuration is either defined in your `_config.php`, or through `.env`
* Sets up [error handlers](../debugging/error_handling)
* Optionally continues a [session](../cookies_and_sessions/sessions) if the request already contains a session identifier
* Loads manifests for PHP classes, templates, as well as any [YAML configuration](../configuration).

View File

@ -44,25 +44,21 @@ This currently only works on UNIX like systems, not on Windows.
Sometimes SilverStripe needs to know the URL of your site. For example, when sending an email or generating static
files. When you're visiting the site in a web browser this is easy to work out, but when executing scripts on the
command line, it has no way of knowing. To work this out, add lines to your
[_ss_environment.php](/getting_started/environment_management) file.
command line, it has no way of knowing. To work this out, there are several ways to resolve this. You can set alternate
base URLs, hosts, and protocol.
:::php
global $_FILE_TO_URL_MAPPING;
eg:
$_FILE_TO_URL_MAPPING['/Users/sminnee/Sites'] = 'http://localhost';
```yml
SilverStripe\Control\Director:
alternate_base_url: 'https://example.com/'
```
The above statement tells SilverStripe that anything executed under the `/Users/sminnee/Sites` directory will have the
base URL `http://localhost`. The site `/Users/sminnee/Sites/my_silverstripe_project` will translate to the URL
`http://localhost/my_silverstripe_project`.
Alternatively you can use the `SS_HOST` environment variable to set a fallback hostname:
You can add multiple file to url mapping definitions. The most specific mapping will be used.
:::php
global $_FILE_TO_URL_MAPPING;
$_FILE_TO_URL_MAPPING['/Users/sminnee/Sites'] = 'http://localhost';
$_FILE_TO_URL_MAPPING['/Users/sminnee/Sites/my_silverstripe_project'] = 'http://project.localhost';
```
SS_HOST="localhost"
```
### Usage

View File

@ -49,6 +49,7 @@ guide developers in preparing existing 3.x code for compatibility with 4.0
* Themes are now configured to cascade, where you can specify a list of themes, and have the template engine
search programatically through a prioritised list when resolving template and CSS file paths.
* i18n Updated to use symfony/translation over zend Framework 1. Zend_Translate has been removed.
* _ss_environment.php files have been removed in favour of `.env` and "real" environment variables.
## <a name="upgrading"></a>Upgrading
@ -1327,7 +1328,7 @@ handle field-level and form-level messages. This has the following properties:
### <a name="overview-mailer"></a>Email and Mailer
#### <a name="overview-orm-api"></a>Email Additions / Changes
#### <a name="overview-mailer-api"></a>Email Additions / Changes
* `Mailer` converted to an interface
* `SwfitMailer` added as new default mailer
@ -1335,3 +1336,20 @@ handle field-level and form-level messages. This has the following properties:
* Default template body variable renamed from `$Body` to `$EmailContent`
* `$email->setTemplate()` renamed to `$email->setHTMLTemplate()`
* Added `$email->setPlainTemplate` for rendering plain versions of email
### <a name="overview-environment-management"></a>Environment management
See [Environment Management docs](https://docs.silverstripe.org/en/4/getting_started/environment_management/) for full
details.
The removal of the `_ss_environment.php` file means that conditional logic is no longer available in the environment
varialbe set-up process. This generally encouraged bad practice and should be avoided. If you still require conditional
logic early in the bootstrap, this is best placed in the `_config.php` files.
#### Environment file changes
* Removed support for _ss_environment.php in favour of .env and first class environment variables
* Environment variables now can be set in `.env` file placed in webroot or one level above
* Environment variables will be read from the environment as well
* `$_FILE_TO_URL_MAPPING` has been removed and replaced with using `Director.alternate_host` or `SS_HOST` env var

View File

@ -75,7 +75,7 @@ This change could be committed to a minor release like *3.2.0*, and remains depr
(e.g. *3.3.0*, *3.4.0*), until a new major release (e.g. *4.0.0*), at which point it gets removed from the codebase.
Deprecation notices are enabled by default on dev environment, but can be
turned off via either _ss_environment.php or in your _config.php. Deprecation
turned off via either `.env` or in your _config.php. Deprecation
notices are always disabled on both live and test.
@ -86,11 +86,10 @@ notices are always disabled on both live and test.
Deprecation::set_enabled(false);
`_ss_environment.php`
`.env`
:::php
define('SS_DEPRECATION_ENABLED', false);
SS_DEPRECATION_ENABLED="0"
## Security Releases

View File

@ -36,32 +36,29 @@ As a core contributor it is necessary to have installed the following set of too
* [AWS CLI tools](https://aws.amazon.com/cli/):
`pip install awscli`
* The `tar` and `zip` commands
* A good _ss_environment.php setup in your localhost webroot.
* A good `.env` setup in your localhost webroot.
Example `_ss_environment.php`:
Example `.env`:
:::php
<?php
// Environent
define('SS_TRUSTED_PROXY_IPS', '*');
define('SS_ENVIRONMENT_TYPE', 'dev');
# Environent
SS_TRUSTED_PROXY_IPS="*"
SS_ENVIRONMENT_TYPE="dev"
// DB Credentials
define('SS_DATABASE_CLASS', 'MySQLDatabase');
define('SS_DATABASE_SERVER', '127.0.0.1');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '');
# DB Credentials
SS_DATABASE_CLASS="MySQLDatabase"
SS_DATABASE_SERVER="127.0.0.1"
SS_DATABASE_USERNAME="root"
SS_DATABASE_PASSWORD=""
// Each release will have its own DB
define('SS_DATABASE_CHOOSE_NAME', true);
# Each release will have its own DB
SS_DATABASE_CHOOSE_NAME=1
// So you can test releases
define('SS_DEFAULT_ADMIN_USERNAME', 'admin');
define('SS_DEFAULT_ADMIN_PASSWORD', 'password');
# So you can test releases
SS_DEFAULT_ADMIN_USERNAME="admin"
SS_DEFAULT_ADMIN_PASSWORD="password"
// Basic CLI hostname
global $_FILE_TO_URL_MAPPING;
$_FILE_TO_URL_MAPPING[__DIR__] = "http://localhost";
# Basic CLI hostname
SS_HOST="localhost";
You will also need to be assigned the following permissions. Contact one of the SS staff from
@ -198,7 +195,7 @@ and needs to be manually advanced):
back up to transifex to make them available for translation. Changes to these
files will also be automatically committed to git.
* `release:test` Will run all unit tests on this release. Make sure that you
setup your `_ss_environment.php` correctly (as above) so that this will work.
setup your `.env` correctly (as above) so that this will work.
* `release:changelog` Will compare the current branch head with `--from` parameter
version in order to generate a changelog file. This wil be placed into the
`./framework/docs/en/04_Changelogs/` folder. If an existing file named after

View File

@ -32,8 +32,7 @@ if (version_compare(phpversion(), '5.5.0', '<')) {
*
* The main.php does a number of set-up activities for the request.
*
* - Includes the first one of the following files that it finds: (root)/_ss_environment.php,
* (root)/../_ss_environment.php, or (root)/../../_ss_environment.php
* - Includes the .env file in your webroot
* - Gets an up-to-date manifest from {@link ManifestBuilder}
* - Sets up error handlers with {@link Debug::loadErrorHandlers()}
* - Calls {@link DB::connect()}, passing it the global variable $databaseConfig that should
@ -189,8 +188,9 @@ if(!isset($databaseConfig) || !isset($databaseConfig['database']) || !$databaseC
header($_SERVER['SERVER_PROTOCOL'] . " 500 Server Error");
die('SilverStripe Framework requires a $databaseConfig defined.');
}
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
$s = (isset($_SERVER['SSL']) || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) ? 's' : '';
$installURL = "http$s://" . $_SERVER['HTTP_HOST'] . BASE_URL . '/install.php';
$installURL = "http$s://" . $host . BASE_URL . '/install.php';
// The above dirname() will equate to "\" on Windows when installing directly from http://localhost (not using
// a sub-directory), this really messes things up in some browsers. Let's get rid of the backslashes

View File

@ -35,13 +35,8 @@ class ProtectedAssetAdapter extends AssetAdapter implements ProtectedAdapter
return parent::findRoot($root);
}
// Use environment defined path
if (defined('SS_PROTECTED_ASSETS_PATH')) {
return SS_PROTECTED_ASSETS_PATH;
}
// Default location is under assets
return ASSETS_PATH . '/' . Config::inst()->get(get_class($this), 'secure_folder');
// Use environment defined path or default location is under assets
return getenv('SS_PROTECTED_ASSETS_PATH') ?: ASSETS_PATH . '/' . Config::inst()->get(get_class($this), 'secure_folder');
}
/**

View File

@ -101,6 +101,13 @@ class Director implements TemplateGlobalProvider
*/
private static $alternate_protocol;
/**
* @config
*
* @var string
*/
private static $alternate_host;
/**
* @config
*
@ -139,6 +146,15 @@ class Director implements TemplateGlobalProvider
*/
public static function direct($url, DataModel $model)
{
// check allowed hosts
if (getenv('SS_ALLOWED_HOSTS') && !Director::is_cli()) {
$all_allowed_hosts = explode(',', getenv('SS_ALLOWED_HOSTS'));
if (!in_array(static::host(), $all_allowed_hosts)) {
throw new HTTPResponse_Exception('Invalid Host', 400);
}
}
// Validate $_FILES array before merging it with $_POST
foreach ($_FILES as $k => $v) {
if (is_array($v['tmp_name'])) {
@ -551,6 +567,62 @@ class Director implements TemplateGlobalProvider
return Controller::join_links($parent, $url);
}
/**
* A helper to determine the current hostname used to access the site.
* The following are used to determine the host (in order)
* - Director.alternate_host
* - Director.alternate_base_url (if it contains a domain name)
* - Trusted proxy headers
* - HTTP Host header
* - SS_HOST env var
* - SERVER_NAME
* - gethostname()
*
* @return string
*/
public static function host()
{
$headerOverride = false;
if (TRUSTED_PROXY) {
$headers = (getenv('SS_TRUSTED_PROXY_HOST_HEADER')) ? array(getenv('SS_TRUSTED_PROXY_HOST_HEADER')) : null;
if (!$headers) {
// Backwards compatible defaults
$headers = array('HTTP_X_FORWARDED_HOST');
}
foreach ($headers as $header) {
if (!empty($_SERVER[$header])) {
// Get the first host, in case there's multiple separated through commas
$headerOverride = strtok($_SERVER[$header], ',');
break;
}
}
}
if ($host = static::config()->get('alternate_host')) {
return $host;
}
if ($baseURL = static::config()->get('alternate_base_url')) {
if (preg_match('/^(http[^:]*:\/\/[^\/]+)(\/|$)/', $baseURL, $matches)) {
return parse_url($baseURL, PHP_URL_HOST);
}
}
if ($headerOverride) {
return $headerOverride;
}
if (isset($_SERVER['HTTP_HOST'])) {
return $_SERVER['HTTP_HOST'];
}
if ($host = getenv('SS_HOST')) {
return $host;
}
return isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : gethostname();
}
/**
* Returns the domain part of the URL 'http://www.mysite.com'. Returns FALSE is this environment
* variable isn't set.
@ -559,31 +631,7 @@ class Director implements TemplateGlobalProvider
*/
public static function protocolAndHost()
{
$alternate = Config::inst()->get('SilverStripe\\Control\\Director', 'alternate_base_url');
if ($alternate) {
if (preg_match('/^(http[^:]*:\/\/[^\/]+)(\/|$)/', $alternate, $matches)) {
return $matches[1];
}
}
if (isset($_SERVER['HTTP_HOST'])) {
return Director::protocol() . $_SERVER['HTTP_HOST'];
} else {
global $_FILE_TO_URL_MAPPING;
if (Director::is_cli() && isset($_FILE_TO_URL_MAPPING)) {
$errorSuggestion = ' You probably want to define ' .
'an entry in $_FILE_TO_URL_MAPPING that covers "' . Director::baseFolder() . '"';
} elseif (Director::is_cli()) {
$errorSuggestion = ' You probably want to define $_FILE_TO_URL_MAPPING in ' .
'your _ss_environment.php as instructed on the "sake" page of the doc.silverstripe.com wiki';
} else {
$errorSuggestion = "";
}
user_error("Director::protocolAndHost() lacks sufficient information - HTTP_HOST not set."
. $errorSuggestion, E_USER_WARNING);
return false;
}
return static::protocol() . static::host();
}
/**
@ -607,7 +655,7 @@ class Director implements TemplateGlobalProvider
// See https://support.microsoft.com/en-us/kb/307347
$headerOverride = false;
if (TRUSTED_PROXY) {
$headers = (defined('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(SS_TRUSTED_PROXY_PROTOCOL_HEADER) : null;
$headers = (getenv('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(getenv('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) : null;
if (!$headers) {
// Backwards compatible defaults
$headers = array('HTTP_X_FORWARDED_PROTO', 'HTTP_X_FORWARDED_PROTOCOL', 'HTTP_FRONT_END_HTTPS');
@ -950,7 +998,7 @@ class Director implements TemplateGlobalProvider
$login = "$_SERVER[PHP_AUTH_USER]:$_SERVER[PHP_AUTH_PW]@";
}
return Director::protocol() . $login . $_SERVER['HTTP_HOST'] . Director::baseURL();
return Director::protocol() . $login . static::host() . Director::baseURL();
}
/**
@ -1052,7 +1100,7 @@ class Director implements TemplateGlobalProvider
*/
public static function forceWWW()
{
if (!Director::isDev() && !Director::isTest() && strpos($_SERVER['HTTP_HOST'], 'www') !== 0) {
if (!Director::isDev() && !Director::isTest() && strpos(static::host(), 'www') !== 0) {
$destURL = str_replace(
Director::protocol(),
Director::protocol() . 'www.',
@ -1191,11 +1239,7 @@ class Director implements TemplateGlobalProvider
// Check if we are running on one of the test servers
$devServers = (array)Config::inst()->get('SilverStripe\\Control\\Director', 'dev_servers');
if (isset($_SERVER['HTTP_HOST']) && in_array($_SERVER['HTTP_HOST'], $devServers)) {
return true;
}
return false;
return in_array(static::host(), $devServers);
}
/**
@ -1223,11 +1267,7 @@ class Director implements TemplateGlobalProvider
// Check if we are running on one of the test servers
$testServers = (array)Config::inst()->get('SilverStripe\\Control\\Director', 'test_servers');
if (isset($_SERVER['HTTP_HOST']) && in_array($_SERVER['HTTP_HOST'], $testServers)) {
return true;
}
return false;
return in_array(static::host(), $testServers);
}
/**

View File

@ -768,7 +768,7 @@ class HTTPRequest implements ArrayAccess
{
$headerOverrideIP = null;
if (TRUSTED_PROXY) {
$headers = (defined('SS_TRUSTED_PROXY_IP_HEADER')) ? array(SS_TRUSTED_PROXY_IP_HEADER) : null;
$headers = (getenv('SS_TRUSTED_PROXY_IP_HEADER')) ? array(getenv('SS_TRUSTED_PROXY_IP_HEADER')) : null;
if (!$headers) {
// Backwards compatible defaults
$headers = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR');

View File

@ -3,7 +3,6 @@
* This file is the Framework constants bootstrap. It will prepare some basic common constants.
*
* It takes care of:
* - Including _ss_environment.php
* - Normalisation of $_SERVER values
* - Initialisation of necessary constants (mostly paths)
*
@ -30,48 +29,6 @@
///////////////////////////////////////////////////////////////////////////////
// ENVIRONMENT CONFIG
/**
* Include _ss_environment.php file
*/
//define the name of the environment file
$envFile = '_ss_environment.php';
//define the dirs to start scanning from (have to add the trailing slash)
// we're going to check the realpath AND the path as the script sees it
$dirsToCheck = array(
realpath('.'),
dirname($_SERVER['SCRIPT_FILENAME'])
);
//if they are the same, remove one of them
if ($dirsToCheck[0] == $dirsToCheck[1]) {
unset($dirsToCheck[1]);
}
foreach ($dirsToCheck as $dir) {
//check this dir and every parent dir (until we hit the base of the drive)
// or until we hit a dir we can't read
while (true) {
//if it's readable, go ahead
if (@is_readable($dir)) {
//if the file exists, then we include it, set relevant vars and break out
if (file_exists($dir . DIRECTORY_SEPARATOR . $envFile)) {
define('SS_ENVIRONMENT_FILE', $dir . DIRECTORY_SEPARATOR . $envFile);
include_once(SS_ENVIRONMENT_FILE);
//break out of BOTH loops because we found the $envFile
break(2);
}
} else {
//break out of the while loop, we can't read the dir
break;
}
if (dirname($dir) == $dir) {
// here we need to check that the path of the last dir and the next one are
// not the same, if they are, we have hit the root of the drive
break;
}
//go up a directory
$dir = dirname($dir);
}
}
/**
* Validate whether the request comes directly from a trusted server or not
* This is necessary to validate whether or not the values of X-Forwarded-
@ -82,18 +39,18 @@ if (!defined('TRUSTED_PROXY')) {
if (getenv('BlockUntrustedProxyHeaders') // Legacy setting (reverted from documentation)
|| getenv('BlockUntrustedIPs') // Documented setting
|| defined('SS_TRUSTED_PROXY_IPS')
|| getenv('SS_TRUSTED_PROXY_IPS')
) {
$trusted = false;
if (defined('SS_TRUSTED_PROXY_IPS') && SS_TRUSTED_PROXY_IPS !== 'none') {
if (SS_TRUSTED_PROXY_IPS === '*') {
if (getenv('SS_TRUSTED_PROXY_IPS') !== 'none') {
if (getenv('SS_TRUSTED_PROXY_IPS') === '*') {
$trusted = true;
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
if (!class_exists('SilverStripe\\Control\\Util\\IPUtils')) {
require_once 'Control/IPUtils.php';
};
$trusted = SilverStripe\Control\Util\IPUtils::checkIP($_SERVER['REMOTE_ADDR'], explode(',', SS_TRUSTED_PROXY_IPS));
$trusted = SilverStripe\Control\Util\IPUtils::checkIP($_SERVER['REMOTE_ADDR'], explode(',', getenv('SS_TRUSTED_PROXY_IPS')));
}
}
}
@ -104,80 +61,6 @@ if (!defined('TRUSTED_PROXY')) {
define('TRUSTED_PROXY', $trusted);
}
/**
* A blank HTTP_HOST value is used to detect command-line execution.
* We update the $_SERVER variable to contain data consistent with the rest of the application.
*/
if (!isset($_SERVER['HTTP_HOST'])) {
// HTTP_HOST, REQUEST_PORT, SCRIPT_NAME, and PHP_SELF
global $_FILE_TO_URL_MAPPING;
if (isset($_FILE_TO_URL_MAPPING)) {
$fullPath = $testPath = realpath($_SERVER['SCRIPT_FILENAME']);
while ($testPath && $testPath != '/' && !preg_match('/^[A-Z]:\\\\$/', $testPath)) {
if (isset($_FILE_TO_URL_MAPPING[$testPath])) {
$url = $_FILE_TO_URL_MAPPING[$testPath]
. str_replace(DIRECTORY_SEPARATOR, '/', substr($fullPath, strlen($testPath)));
$components = parse_url($url);
$_SERVER['HTTP_HOST'] = $components['host'];
if (!empty($components['port'])) {
$_SERVER['HTTP_HOST'] .= ':' . $components['port'];
}
$_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'] = $components['path'];
if (!empty($components['port'])) {
$_SERVER['REQUEST_PORT'] = $components['port'];
}
break;
}
$testPath = dirname($testPath);
}
}
// Everything else
$serverDefaults = array(
'SERVER_PROTOCOL' => 'HTTP/1.1',
'HTTP_ACCEPT' => 'text/plain;q=0.5',
'HTTP_ACCEPT_LANGUAGE' => '*;q=0.5',
'HTTP_ACCEPT_ENCODING' => '',
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1;q=0.5',
'SERVER_SIGNATURE' => 'Command-line PHP/' . phpversion(),
'SERVER_SOFTWARE' => 'PHP/' . phpversion(),
'SERVER_ADDR' => '127.0.0.1',
'REMOTE_ADDR' => '127.0.0.1',
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => 'CLI',
);
$_SERVER = array_merge($serverDefaults, $_SERVER);
/**
* If we have an HTTP_HOST value, then we're being called from the webserver and there are some things that
* need checking
*/
} else {
/**
* Fix HTTP_HOST from reverse proxies
*/
$trustedProxyHeader = (defined('SS_TRUSTED_PROXY_HOST_HEADER'))
? SS_TRUSTED_PROXY_HOST_HEADER
: 'HTTP_X_FORWARDED_HOST';
if (TRUSTED_PROXY && !empty($_SERVER[$trustedProxyHeader])) {
// Get the first host, in case there's multiple separated through commas
$_SERVER['HTTP_HOST'] = strtok($_SERVER[$trustedProxyHeader], ',');
}
}
// Filter by configured allowed hosts
if (defined('SS_ALLOWED_HOSTS') && php_sapi_name() !== "cli") {
$all_allowed_hosts = explode(',', SS_ALLOWED_HOSTS);
if (!isset($_SERVER['HTTP_HOST']) || !in_array($_SERVER['HTTP_HOST'], $all_allowed_hosts)) {
header('HTTP/1.1 400 Invalid Host', true, 400);
die();
}
}
/**
* Define system paths
*/
@ -202,6 +85,23 @@ if (!defined('BASE_PATH')) {
}
define('BASE_PATH', $candidateBasePath);
}
// Allow a first class env var to be set that disables .env file loading
if (!getenv('SS_IGNORE_DOT_ENV')) {
foreach (array(
BASE_PATH,
dirname(BASE_PATH),
) as $path) {
try {
(new \Dotenv\Dotenv($path))->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
// no .env found - no big deal
continue;
}
break;
}
}
if (!defined('BASE_URL')) {
// Determine the base URL by comparing SCRIPT_NAME to SCRIPT_FILENAME and getting common elements
$path = realpath($_SERVER['SCRIPT_FILENAME']);

View File

@ -176,7 +176,7 @@ class ClassManifest
$this->base = $base;
$this->tests = $includeTests;
$cacheClass = defined('SS_MANIFESTCACHE') ? SS_MANIFESTCACHE : 'SilverStripe\\Core\\Manifest\\ManifestCache_File';
$cacheClass = getenv('SS_MANIFESTCACHE') ?: 'SilverStripe\\Core\\Manifest\\ManifestCache_File';
$this->cache = new $cacheClass('classmanifest'.($includeTests ? '_tests' : ''));
$this->cacheKey = 'manifest';

View File

@ -210,7 +210,7 @@ class ConfigManifest
if (isset($key['envvars'])) {
foreach ($key['envvars'] as $variable => $foo) {
$key['envvars'][$variable] = isset($_ENV[$variable]) ? $_ENV[$variable] : null;
$key['envvars'][$variable] = getenv($variable) ?: null;
}
}
@ -726,7 +726,7 @@ class ConfigManifest
break;
case 'envvarset':
$matches = $matches && isset($_ENV[$v]);
$matches = $matches && getenv($v);
break;
case 'constantdefined':
@ -735,7 +735,7 @@ class ConfigManifest
default:
$matches = $matches && (
(isset($_ENV[$k]) && $_ENV[$k] == $v) ||
getenv($k) == $v ||
(defined($k) && constant($k) == $v)
);
break;

View File

@ -2,6 +2,7 @@
namespace SilverStripe\Core\Startup;
use SilverStripe\Control\Director;
use SilverStripe\Security\RandomGenerator;
/**
@ -179,7 +180,7 @@ class ParameterConfirmationToken
// See https://support.microsoft.com/en-us/kb/307347
$headerOverride = false;
if (TRUSTED_PROXY) {
$headers = (defined('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(SS_TRUSTED_PROXY_PROTOCOL_HEADER) : null;
$headers = (getenv('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(getenv('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) : null;
if (!$headers) {
// Backwards compatible defaults
$headers = array('HTTP_X_FORWARDED_PROTO', 'HTTP_X_FORWARDED_PROTOCOL', 'HTTP_FRONT_END_HTTPS');
@ -203,7 +204,7 @@ class ParameterConfirmationToken
$parts = array_filter(array(
// What's our host
$_SERVER['HTTP_HOST'],
Director::host(),
// SilverStripe base
self::$alternateBaseURL !== null ? self::$alternateBaseURL : BASE_URL,
// And URL including base script (eg: if it's index.php/page/url/)

View File

@ -152,10 +152,7 @@ class Deprecation
if (isset(self::$enabled)) {
return self::$enabled;
}
if (defined('SS_DEPRECATION_ENABLED')) {
return SS_DEPRECATION_ENABLED;
}
return true;
return getenv('SS_DEPRECATION_ENABLED') ?: true;
}
/**

View File

@ -64,31 +64,6 @@ class DevelopmentAdmin extends Controller
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.

View File

@ -2,7 +2,7 @@ $(document).ready(function () {
/**
* Toggle field readonly modes, if check configuration comes from
* _ss_environment (values populated on reload).
* environment variables (values populated on reload).
*/
$('#use_environment').click(function (e) {
if (!$(this).is(':checked')) {

View File

@ -101,7 +101,7 @@
// All are disabled by default when environment is used
$disabled = 'disabled="disabled"';
// If SS_DATABASE_CLASS is specified, check the database in the list
if(defined('SS_DATABASE_CLASS') && SS_DATABASE_CLASS == $class) {
if(getenv('SS_DATABASE_CLASS') == $class) {
$checked = ' checked="checked"';
}
} else {
@ -135,8 +135,8 @@
$fieldType = ($fieldName == 'password') ? 'password' : 'text';
// values
$defaultValue = (isset($fieldSpec['default'])) ? $fieldSpec['default'] : null;
if($usingEnv && isset($fieldSpec['envVar']) && defined($fieldSpec['envVar'])) {
$value = constant($fieldSpec['envVar']);
if($usingEnv && isset($fieldSpec['envVar']) && $envVar = getenv($fieldSpec['envVar'])) {
$value = $envVar;
} else {
$value = (isset($databaseConfig[$fieldName]) && $databaseConfig['type'] == $class) ? $databaseConfig[$fieldName] : $defaultValue;
}
@ -149,7 +149,7 @@
'name' => "db[$class][$fieldName]",
'value' => $value,
);
if($usingEnv && isset($fieldSpec['envVar']) && defined($fieldSpec['envVar'])) {
if($usingEnv && isset($fieldSpec['envVar']) && getenv($fieldSpec['envVar'])) {
$attrs['disabled'] = 'disabled';
}
if(isset($fieldSpec['envVar'])) {
@ -177,7 +177,7 @@
<?php if($envFileExists) { ?>
<div id="use_environment_field" class="field">
<input id="use_environment" type="checkbox" name="useEnv" <?php if($usingEnv) echo "checked=\"checked\"" ?>>
<label for="use_environment">Use _ss_environment file for configuration (<a href="http://doc.silverstripe.org/framework/en/topics/environment-management" target="_blank">?</a>)</label>
<label for="use_environment">Use environment variables for configuration (<a href="http://doc.silverstripe.org/framework/en/topics/environment-management" target="_blank">?</a>)</label>
</div>
<?php } ?>
@ -202,14 +202,14 @@
<div class="field">
<label for="admin_username">Email:</label>
<span class="middleColumn">
<input type="text" class="text configured-by-env" name="admin[username]" id="admin_username" value="<?php echo htmlspecialchars($adminConfig['username'], ENT_QUOTES, 'UTF-8'); ?>" <?php if($usingEnv && defined('SS_DEFAULT_ADMIN_USERNAME')) echo 'disabled="disabled"' ?>>
<input type="text" class="text configured-by-env" name="admin[username]" id="admin_username" value="<?php echo htmlspecialchars($adminConfig['username'], ENT_QUOTES, 'UTF-8'); ?>" <?php if($usingEnv && getenv('SS_DEFAULT_ADMIN_USERNAME')) echo 'disabled="disabled"' ?>>
</span>
</div>
<div class="field">
<label for="admin_password">Password:</label>
<span class="middleColumn">
<input type="password" class="text configured-by-env" name="admin[password]" id="admin_password" value="<?php echo htmlspecialchars($adminConfig['password'], ENT_QUOTES, 'UTF-8'); ?>" <?php if($usingEnv && defined('SS_DEFAULT_ADMIN_PASSWORD')) echo 'disabled="disabled"' ?>>
<input type="password" class="text configured-by-env" name="admin[password]" id="admin_password" value="<?php echo htmlspecialchars($adminConfig['password'], ENT_QUOTES, 'UTF-8'); ?>" <?php if($usingEnv && getenv('SS_DEFAULT_ADMIN_PASSWORD')) echo 'disabled="disabled"' ?>>
</span>
</div>
</div>

View File

@ -60,8 +60,7 @@ if (!$included) {
exit(1);
}
$envFileExists = defined('SS_ENVIRONMENT_FILE');
$usingEnv = $envFileExists && !empty($_REQUEST['useEnv']);
$usingEnv = !empty($_REQUEST['useEnv']);
require_once __DIR__ . '/DatabaseConfigurationHelper.php';
require_once __DIR__ . '/DatabaseAdapterRegistry.php';
@ -142,8 +141,8 @@ if(isset($_REQUEST['db'])) {
if(isset($_REQUEST['db']['type'])) {
$type = $_REQUEST['db']['type'];
} else {
if( defined('SS_DATABASE_CLASS') ){
$type = $_REQUEST['db']['type'] = SS_DATABASE_CLASS;
if ($type = getenv('SS_DATABASE_CLASS')) {
$_REQUEST['db']['type'] = $type;
} elseif( $databaseClasses['MySQLPDODatabase']['supported'] ) {
$type = $_REQUEST['db']['type'] = 'MySQLPDODatabase';
} elseif( $databaseClasses['MySQLDatabase']['supported'] ) {
@ -156,10 +155,10 @@ if(isset($_REQUEST['db'])) {
// Disabled inputs don't submit anything - we need to use the environment (except the database name)
if($usingEnv) {
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"type" => getenv('SS_DATABASE_CLASS') ?: $type,
"server" => getenv('SS_DATABASE_SERVER') ?: "localhost",
"username" => getenv('SS_DATABASE_USERNAME') ?: "root",
"password" => getenv('SS_DATABASE_PASSWORD') ?: "",
"database" => $_REQUEST['db'][$type]['database'],
);
@ -169,8 +168,8 @@ if(isset($_REQUEST['db'])) {
$databaseConfig['type'] = $type;
}
} else {
if( defined('SS_DATABASE_CLASS') ){
$type = $_REQUEST['db']['type'] = SS_DATABASE_CLASS;
if($type = getenv('SS_DATABASE_CLASS')) {
$_REQUEST['db']['type'] = $type;
} elseif( $databaseClasses['MySQLPDODatabase']['supported'] ) {
$type = $_REQUEST['db']['type'] = 'MySQLPDODatabase';
} elseif( $databaseClasses['MySQLDatabase']['supported'] ) {
@ -180,9 +179,9 @@ if(isset($_REQUEST['db'])) {
}
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"server" => getenv('SS_DATABASE_SERVER') ?: "localhost",
"username" => getenv('SS_DATABASE_USERNAME') ?: "root",
"password" => getenv('SS_DATABASE_PASSWORD') ?: "",
"database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite",
);
}
@ -191,16 +190,16 @@ if(isset($_REQUEST['admin'])) {
// Disabled inputs don't submit anything - we need to use the environment (except the database name)
if($usingEnv) {
$_REQUEST['admin'] = $adminConfig = array(
'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin',
'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '',
'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
);
} else {
$adminConfig = $_REQUEST['admin'];
}
} else {
$_REQUEST['admin'] = $adminConfig = array(
'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin',
'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '',
'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
);
}
@ -1402,7 +1401,7 @@ class Installer extends InstallRequirements {
// Write the config file
global $usingEnv;
if($usingEnv) {
$this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php...");
$this->statusMessage("Setting up 'mysite/_config.php' for use with environment variables...");
$this->writeToFile("mysite/_config.php", <<<PHP
<?php

View File

@ -1026,7 +1026,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
public static function using_temp_db()
{
$dbConn = DB::get_conn();
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
$prefix = getenv('SS_DATABASE_PREFIX') ?: 'ss_';
return $dbConn && (substr($dbConn->getSelectedDatabase(), 0, strlen($prefix) + 5)
== strtolower(sprintf('%stmpdb', $prefix)));
}
@ -1083,7 +1083,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
$databaseConfig['timezone'] = '+0:00';
DB::connect($databaseConfig);
$dbConn = DB::get_conn();
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
$prefix = getenv('SS_DATABASE_PREFIX') ?: 'ss_';
$dbname = strtolower(sprintf('%stmpdb', $prefix)) . rand(1000000, 9999999);
while (!$dbname || $dbConn->databaseExists($dbname)) {
$dbname = strtolower(sprintf('%stmpdb', $prefix)) . rand(1000000, 9999999);
@ -1103,7 +1103,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
public static function delete_all_temp_dbs()
{
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
$prefix = getenv('SS_DATABASE_PREFIX') ?: 'ss_';
foreach (DB::get_schema()->databaseList() as $dbName) {
if (preg_match(sprintf('/^%stmpdb[0-9]+$/', $prefix), $dbName)) {
DB::get_schema()->dropDatabase($dbName);

View File

@ -241,7 +241,7 @@ class DB
return false;
}
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
$prefix = getenv('SS_DATABASE_PREFIX') ?: 'ss_';
$pattern = strtolower(sprintf('/^%stmpdb\d{7}$/', $prefix));
return (bool)preg_match($pattern, $name);
}

View File

@ -134,9 +134,9 @@ class BasicAuth
* away from prying eyes, but still be able to test the regular log-in features of the site.
*
* If you are including conf/ConfigureFromEnv.php in your _config.php file, you can also enable
* this feature by adding this line to your _ss_environment.php:
* this feature by adding this line to your .env:
*
* define('SS_USE_BASIC_AUTH', true);
* SS_USE_BASIC_AUTH=1
*
* @param boolean $protect Set this to false to disable protection.
* @param string $code {@link Permission} code that is required from the user.

View File

@ -72,9 +72,8 @@ class ThemeManifest implements ThemeList
$this->project = $project;
$cacheClass = defined('SS_MANIFESTCACHE')
? SS_MANIFESTCACHE
: 'SilverStripe\\Core\\Manifest\\ManifestCache_File';
$cacheClass = getenv('SS_MANIFESTCACHE')
?: 'SilverStripe\\Core\\Manifest\\ManifestCache_File';
$this->cache = new $cacheClass('thememanifest'.($includeTests ? '_tests' : ''));
$this->cacheKey = $this->getCacheKey();

View File

@ -1,9 +1,9 @@
<?php
/**
* Configure SilverStripe from the _ss_environment.php file.
* Configure SilverStripe from the environment variables.
* Usage: Put "require_once('conf/ConfigureFromEnv.php');" into your _config.php file.
*
* If you include this file, you will be able to use the following defines in _ss_environment.php to control
* If you include this file, you will be able to use the following variables to control
* your site.
*
* Your database connection will be set up using these defines:
@ -55,49 +55,27 @@ use SilverStripe\Dev\Install\DatabaseAdapterRegistry;
use SilverStripe\Security\BasicAuth;
use SilverStripe\Security\Security;
/*
* _ss_environment.php handler
*/
if (defined('SS_ENVIRONMENT_FILE')) {
// Only perform validation if SS_ENVIRONMENT_FILE is actually set, which is to say, there is an
// _ss_environment.php file
foreach (array(
'SS_DATABASE_PASSWORD',
'SS_DATABASE_USERNAME',
'SS_ENVIRONMENT_TYPE',) as $reqDefine) {
if (!defined($reqDefine)) {
user_error(
"$reqDefine must be defined in your _ss_environment.php."
. "See http://doc.silverstripe.org/framework/en/topics/environment-management for more information",
E_USER_ERROR
);
}
}
}
if (defined('SS_ENVIRONMENT_TYPE')) {
Director::config()->environment_type = SS_ENVIRONMENT_TYPE;
if ($envType = getenv('SS_ENVIRONMENT_TYPE')) {
Director::config()->environment_type = $envType;
}
global $database;
// No database provided
if (!isset($database) || !$database) {
if (defined('SS_DATABASE_NAME')) {
$database = SS_DATABASE_NAME;
} elseif (defined('SS_DATABASE_CHOOSE_NAME') && SS_DATABASE_CHOOSE_NAME) {
$loopCount = (int)SS_DATABASE_CHOOSE_NAME;
if (!($database = getenv('SS_DATABASE_NAME')) && $chooseName = getenv('SS_DATABASE_CHOOSE_NAME')) {
$loopCount = (int)$chooseName;
$databaseDir = BASE_PATH;
for ($i=0; $i<$loopCount-1;
$i++) {
for ($i=0; $i<$loopCount-1; $i++) {
$databaseDir = dirname($databaseDir);
}
$database = "SS_" . basename($databaseDir);
$database = getenv('SS_DATABASE_PREFIX') ?: 'SS_';
$database .= basename($databaseDir);
$database = str_replace('.', '', $database);
}
}
if (defined('SS_DATABASE_USERNAME') && defined('SS_DATABASE_PASSWORD')) {
if ($dbUser = getenv('SS_DATABASE_USERNAME')) {
global $databaseConfig;
// Checks if the database global is defined (if present, wraps with prefix and suffix)
@ -105,69 +83,69 @@ if (defined('SS_DATABASE_USERNAME') && defined('SS_DATABASE_PASSWORD')) {
if (!$name) {
return '';
} else {
return (defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : '')
return (getenv('SS_DATABASE_PREFIX') ?: '')
. $name
. (defined('SS_DATABASE_SUFFIX') ? SS_DATABASE_SUFFIX : '');
. (getenv('SS_DATABASE_SUFFIX') ?: '');
}
};
/** @skipUpgrade */
$databaseConfig = array(
"type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase',
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : 'localhost',
"username" => SS_DATABASE_USERNAME,
"password" => SS_DATABASE_PASSWORD,
"type" => getenv('SS_DATABASE_CLASS') ?: 'MySQLDatabase',
"server" => getenv('SS_DATABASE_SERVER') ?: 'localhost',
"username" => $dbUser,
"password" => getenv('SS_DATABASE_PASSWORD'),
"database" => $databaseNameWrapper($database),
);
// Set the port if called for
if (defined('SS_DATABASE_PORT')) {
$databaseConfig['port'] = SS_DATABASE_PORT;
if ($dbPort = getenv('SS_DATABASE_PORT')) {
$databaseConfig['port'] = $dbPort;
}
// Set the timezone if called for
if (defined('SS_DATABASE_TIMEZONE')) {
$databaseConfig['timezone'] = SS_DATABASE_TIMEZONE;
if ($dbTZ = getenv('SS_DATABASE_TIMEZONE')) {
$databaseConfig['timezone'] = $dbTZ;
}
// For schema enabled drivers:
if (defined('SS_DATABASE_SCHEMA')) {
$databaseConfig["schema"] = SS_DATABASE_SCHEMA;
if ($dbSchema = getenv('SS_DATABASE_SCHEMA')) {
$databaseConfig["schema"] = $dbSchema;
}
// For SQlite3 memory databases (mainly for testing purposes)
if (defined('SS_DATABASE_MEMORY')) {
$databaseConfig["memory"] = SS_DATABASE_MEMORY;
if ($dbMemory = getenv('SS_DATABASE_MEMORY')) {
$databaseConfig["memory"] = $dbMemory;
}
}
if (defined('SS_SEND_ALL_EMAILS_TO')) {
Email::config()->send_all_emails_to = SS_SEND_ALL_EMAILS_TO;
if ($sendAllEmailsTo = getenv('SS_SEND_ALL_EMAILS_TO')) {
Email::config()->send_all_emails_to = $sendAllEmailsTo;
}
if (defined('SS_SEND_ALL_EMAILS_FROM')) {
Email::config()->send_all_emails_from = SS_SEND_ALL_EMAILS_FROM;
if ($sendAllEmailsFrom = getenv('SS_SEND_ALL_EMAILS_FROM')) {
Email::config()->send_all_emails_from = $sendAllEmailsFrom;
}
if (defined('SS_DEFAULT_ADMIN_USERNAME')) {
if (!defined('SS_DEFAULT_ADMIN_PASSWORD')) {
if ($defaultAdminUser = getenv('SS_DEFAULT_ADMIN_USERNAME')) {
if (!$defaultAdminPass = getenv('SS_DEFAULT_ADMIN_PASSWORD')) {
user_error(
"SS_DEFAULT_ADMIN_PASSWORD must be defined in your _ss_environment.php,"
"SS_DEFAULT_ADMIN_PASSWORD must be defined in your environment,"
. "if SS_DEFAULT_ADMIN_USERNAME is defined. See "
. "http://doc.silverstripe.org/framework/en/topics/environment-management for more information",
E_USER_ERROR
);
} else {
Security::setDefaultAdmin(SS_DEFAULT_ADMIN_USERNAME, SS_DEFAULT_ADMIN_PASSWORD);
Security::setDefaultAdmin($defaultAdminUser, $defaultAdminPass);
}
}
if (defined('SS_USE_BASIC_AUTH') && SS_USE_BASIC_AUTH) {
BasicAuth::config()->entire_site_protected = SS_USE_BASIC_AUTH;
if ($useBasicAuth = getenv('SS_USE_BASIC_AUTH')) {
BasicAuth::config()->entire_site_protected = $useBasicAuth;
}
if (defined('SS_ERROR_LOG')) {
if ($errorLog = getenv('SS_ERROR_LOG')) {
$logger = Injector::inst()->get('Logger');
if ($logger instanceof Logger) {
$logger->pushHandler(new StreamHandler(BASE_PATH . '/' . SS_ERROR_LOG, Logger::WARNING));
$logger->pushHandler(new StreamHandler(BASE_PATH . '/' . $errorLog, Logger::WARNING));
} else {
user_error("SS_ERROR_LOG setting only works with Monolog, you are using another logger", E_USER_WARNING);
}
@ -175,3 +153,24 @@ if (defined('SS_ERROR_LOG')) {
// Allow database adapters to handle their own configuration
DatabaseAdapterRegistry::autoconfigure();
unset(
$envType,
$chooseName,
$loopCount,
$databaseDir,
$i,
$databaseNameWrapper,
$dbUser,
$dbPort,
$dbTZ,
$dbSchema,
$dbMemory,
$sendAllEmailsTo,
$sendAllEmailsFrom,
$defaultAdminUser,
$defaultAdminPass,
$useBasicAuth,
$errorLog,
$logger
);

View File

@ -6,6 +6,22 @@ if (!$_SERVER) {
$_SERVER = array();
}
// We update the $_SERVER variable to contain data consistent with the rest of the application.
$_SERVER = array_merge(array(
'SERVER_PROTOCOL' => 'HTTP/1.1',
'HTTP_ACCEPT' => 'text/plain;q=0.5',
'HTTP_ACCEPT_LANGUAGE' => '*;q=0.5',
'HTTP_ACCEPT_ENCODING' => '',
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1;q=0.5',
'SERVER_SIGNATURE' => 'Command-line PHP/' . phpversion(),
'SERVER_SOFTWARE' => 'PHP/' . phpversion(),
'SERVER_NAME' => 'localhost',
'SERVER_ADDR' => '127.0.0.1',
'REMOTE_ADDR' => '127.0.0.1',
'REQUEST_METHOD' => 'GET',
'HTTP_USER_AGENT' => 'CLI',
), $_SERVER);
$frameworkPath = dirname(dirname(__FILE__));
$frameworkDir = basename($frameworkPath);

View File

@ -1,34 +1,37 @@
<?php
// Bootstrap _ss_environment.php
// Bootstrap environment variables
if (!defined('SS_ENVIRONMENT_TYPE')) {
define('SS_ENVIRONMENT_TYPE', 'dev');
use Dotenv\Loader;
$loader = new Loader(null);
if (!getenv('SS_ENVIRONMENT_TYPE')) {
$loader->setEnvironmentVariable('SS_ENVIRONMENT_TYPE', 'dev');
}
if (!defined('SS_DATABASE_CLASS') && !defined('SS_DATABASE_USERNAME')) {
if (!getenv('SS_DATABASE_CLASS') && !getenv('SS_DATABASE_USERNAME')) {
// The default settings let us define the database config via environment vars
// Database connection, including PDO and legacy ORM support
switch (getenv('DB')) {
case "PGSQL";
define('SS_DATABASE_CLASS', getenv('PDO') ? 'PostgrePDODatabase' : 'PostgreSQLDatabase');
define('SS_DATABASE_USERNAME', 'postgres');
define('SS_DATABASE_PASSWORD', '');
break;
$loader->setEnvironmentVariable('SS_DATABASE_CLASS', getenv('PDO') ? 'PostgrePDODatabase' : 'PostgreSQLDatabase');
$loader->setEnvironmentVariable('SS_DATABASE_USERNAME', 'postgres');
$loader->setEnvironmentVariable('SS_DATABASE_PASSWORD', '');
break;
case "SQLITE":
define('SS_DATABASE_CLASS', getenv('PDO') ? 'SQLite3PDODatabase' : 'SQLite3Database');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '');
define('SS_SQLITE_DATABASE_PATH', ':memory:');
$loader->setEnvironmentVariable('SS_DATABASE_CLASS', getenv('PDO') ? 'SQLite3PDODatabase' : 'SQLite3Database');
$loader->setEnvironmentVariable('SS_DATABASE_USERNAME', 'root');
$loader->setEnvironmentVariable('SS_DATABASE_PASSWORD', '');
$loader->setEnvironmentVariable('SS_SQLITE_DATABASE_PATH', ':memory:');
break;
default:
define('SS_DATABASE_CLASS', getenv('PDO') ? 'MySQLPDODatabase' : 'MySQLDatabase');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '');
$loader->setEnvironmentVariable('SS_DATABASE_CLASS', getenv('PDO') ? 'MySQLPDODatabase' : 'MySQLDatabase');
$loader->setEnvironmentVariable('SS_DATABASE_USERNAME', 'root');
$loader->setEnvironmentVariable('SS_DATABASE_PASSWORD', '');
}
define('SS_DATABASE_SERVER', '127.0.0.1');
define('SS_DATABASE_CHOOSE_NAME', true);
$loader->setEnvironmentVariable('SS_DATABASE_SERVER', '127.0.0.1');
$loader->setEnvironmentVariable('SS_DATABASE_CHOOSE_NAME', true);
}

View File

@ -427,7 +427,9 @@ class ConfigManifestTest extends SapphireTest
public function testEnvVarSetRules()
{
$_ENV['ENVVARSET_FOO'] = 1;
$loader = new \Dotenv\Loader(null);
$loader->setEnvironmentVariable('ENVVARSET_FOO', 1);
$config = $this->getConfigFixtureValue('EnvVarSet');
$this->assertEquals(
@ -463,7 +465,9 @@ class ConfigManifestTest extends SapphireTest
public function testEnvOrConstantMatchesValueRules()
{
$_ENV['ENVORCONSTANTMATCHESVALUE_FOO'] = 'Foo';
$loader = new \Dotenv\Loader(null);
$loader->setEnvironmentVariable('ENVORCONSTANTMATCHESVALUE_FOO', 'Foo');
define('ENVORCONSTANTMATCHESVALUE_BAR', 'Bar');
$config = $this->getConfigFixtureValue('EnvOrConstantMatchesValue');
@ -537,7 +541,9 @@ class ConfigManifestTest extends SapphireTest
public function testMultipleRules()
{
$_ENV['MULTIPLERULES_ENVVARIABLESET'] = 1;
$loader = new \Dotenv\Loader(null);
$loader->setEnvironmentVariable('MULTIPLERULES_ENVVARIABLESET', 1);
define('MULTIPLERULES_DEFINEDCONSTANT', 'defined');
$config = $this->getConfigFixtureValue('MultipleRules');

View File

@ -42,7 +42,7 @@ class DevAdminControllerTest extends FunctionalTest
public function testGoodRegisteredControllerOutput()
{
// Check for the controller running from the registered url above
// (we use contains rather than equals because sometimes you get Warning: You probably want to define an entry in $_FILE_TO_URL_MAPPING)
// (we use contains rather than equals because sometimes you get a warning)
$this->assertContains(Controller1::OK_MSG, $this->getCapture('/dev/x1'));
$this->assertContains(Controller1::OK_MSG, $this->getCapture('/dev/x1/y1'));
}

View File

@ -12,7 +12,7 @@ class DBTest extends SapphireTest
public function testValidAlternativeDatabaseName()
{
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
$prefix = getenv('SS_DATABASE_PREFIX') ?: 'ss_';
Director::config()->update('environment_type', 'dev');
$this->assertTrue(DB::valid_alternative_database_name($prefix.'tmpdb1234567'));