Skip to content

Commit

Permalink
Documentation refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
gmazzap committed Mar 18, 2023
1 parent 73fc3a4 commit 54f7a95
Show file tree
Hide file tree
Showing 12 changed files with 458 additions and 328 deletions.
10 changes: 5 additions & 5 deletions docs/01-Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The standard "WordPress way" to do configuration via PHP constants makes having

## How it works

WP Starter is a Composer plugin, which means that it can "listen" to Composer events and perform custom operations. Composer plugins extend Composer similar to how WordPress plugins extend WordPress.
WP Starter is a Composer plugin, which means that it can "listen" to Composer events and perform custom operations. Composer plugins extend Composer similarly to how WordPress plugins extend WordPress.

WP Starter listens to "install" and "update" Composer events to do a series of tasks that prepare the project to be a fully working WordPress site.

Expand All @@ -48,23 +48,23 @@ A standard `composer.json` file that requires both a WordPress core package and
{
"name": "some-author/some-project",
"require": {
"johnpbloch/wordpress": "4.9.*",
"roots/wordpress": ">=6.1",
"wecodemore/wpstarter": "^3"
}
}
```

followed by `composer install` is **everything** required to have a complete Composer-based WordPress website installation.

The snippet above makes use of the non-official WordPress package maintained by [John P. Bloch](https://johnpbloch.com/), that at the moment of writing is the most popular WordPress core package on [packagist.org](https://packagist.org/packages/johnpbloch/wordpress) with its more than 2.5 millions of downloads.
The snippet above makes use of the non-official WordPress package maintained by [Roots](https://roots.io/), that at the moment of writing is the most popular WordPress core package on [packagist.org](https://packagist.org/packages/roots/wordpress) with several millions of downloads ([![Roots WordPress Total Downloads](https://img.shields.io/packagist/dt/roots/wordpress.svg?color=9FC65D&labelColor=3C3D46&style=flat-square)](https://packagist.org/packages/roots/composer)).

Of course this is the bare minimum. WP Starter is quite powerful and flexible and rest of documentation will describe how to configure and make the most out of it.
Of course, this is the bare minimum. WP Starter is quite powerful and flexible and rest of documentation will describe how to configure and make the most out of it.



## Requirements

- PHP 7.0+
- PHP 7.1+
- Composer


Expand Down
70 changes: 37 additions & 33 deletions docs/02-Environment-Variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ WordPress uses a single PHP file, `wp-config.php` that is used to declare PHP co

This approach surely has some advantages (speed above all), but also issues. The main problems are two:

- `wp-config.php` will very likely contain "secrets" that should **not** be kept under version control, but being the file required by WordPress it is hard to conciliate the two things.
- `wp-config.php` does not support multiple environments. Meaning if the same code will be deployed to, for example, to both a "staging" and a "production" server it will be necessary to have two versions of the file. This is possible using separate VCS "branches" (if the VCS of choice supports them), but then we fall into the previous issue of being forced to keep secrets versioned.
- **`wp-config.php` will very likely contain "secrets"** that should **not** be kept under version control, but being the file required by WordPress it is hard to conciliate the two things.
- **`wp-config.php` does not support multiple environments**. Meaning if the same code will be deployed to, for example, to both a "staging" and a "production" server it will be necessary to have two versions of the file. This is possible using separate VCS "branches" (if the VCS of choice supports them), but then we fall into the previous issue of being forced to keep secrets under version control.

This issue is surely not limited to WordPress.

Expand All @@ -39,9 +39,9 @@ For example, those could be set into the webserver ([Apache](https://httpd.apach

As additional advantage, env vars can be set "on the fly" acting on the system, e.g. a continuous integration service can set them without touching the code.

Finally, not being code, env vars don't need to be kept under version control, avoiding the issue of having to keep "secrets" under version control.
Finally, not being code, env vars don't need to be kept under version control, avoiding the issue of having to keep "secrets" in VCS.

It is undeniable that the setting of values on the "bare environment" could be quite cumbersome. This is why many applications and tools support "env files".
It is undeniable that the setting of values on the "bare environment" during development could be quite cumbersome. This is why many applications and tools support "env files".

In the rest of the documentation we will refer to "actual environment" to mean variables set on the server itself, to distinguish from variables set by parsing env files.

Expand Down Expand Up @@ -78,27 +78,27 @@ WP Starter uses Symfony Dotenv Component to load an `.env` file found in the pro

The env vars loaded from the file will never overwrite variables that are set in the actual environment.

Moreover, if the actual environment contains all the variables WP Starter and WordPress need, there's actually no need to load and parse env files, which is **the suggested way to go in production**, for performance reasons.
Moreover, **if the "actual environment" contains all the variables WP Starter and WordPress need, there's no need to load and parse env files, which is the suggested way to go in production**.

Configuring WP Starter to **bypass** the loading of env files is accomplished via the **`WPSTARTER_ENV_LOADED`** env variable, which when set tells WP Starter to assume all variables are in the actual environment.

### Important security note about `.env` file

WP Starter loads an `.env` file found in the project root folder, and it is worth noting that if no additional configuration is made, project root is also the folder assumed as webroot for the project.

This is a non-issue in local-only installations, however it can be quite a serious issue on anything that goes online. In fact, an `.env` file inside webroot could expose secrets stored in it (at very minimum DB credentials).
This is a non-issue in local-only installations, however it can be quite a serious issue on anything that goes on-line. In fact, an `.env` file inside webroot could expose secrets stored in it (at very minimum DB credentials).

To avoid this issue there are at least three different ways:

- Create a subfolder inside project root and use it as webroot, keeping `.env `file one level above, in the project root. This is the approach that will be shown in the *"A Commented Sample `composer.json`"* chapter
- Configure WP Starter to load `.env` file from a folder that is not publicly accessible, e.g. the parent folder of the project root (if project root is also webroot). This can be done via the `env-dir` setting. Learn more in the *"WP Starter Configuration"* chapter.
- Create a subfolder inside project root and use it as webroot, keeping `.env` file one level above, in the project root. This is the approach that will be shown in the [*"A Commented Sample `composer.json`"*](06-A-Commented-Sample-Composer-Json.md) chapter.
- Configure WP Starter to load `.env` file from a folder that is not publicly accessible, like the parent folder of the project root (if project root is also webroot). This can be done via the `env-dir` setting. Learn more in the [*"WP Starter Configuration"*](04-WP-Starter-Configuration.md) chapter.
- Don't use env file in production at all, but store env vars in the actual environment. See documentation on how to do it in [Apache](https://httpd.apache.org/docs/2.4/env.html), and [nginx](http://nginx.org/en/docs/ngx_core_module.html#env). Note that Docker supports an `.env` file as well (see [documentation](https://docs.docker.com/compose/environment-variables/)). By setting env vars that way sensitive application configurations would not be publicly accessible.



## Environment variables and WordPress

Although WP Starter loads env vars (no matter if from file or from actual environment), to work properly WordPress still needs PHP constants to be set with configuration.
Although WP Starter loads env vars (no matter if from file or from actual environment), WordPress still needs PHP constants to be set with configuration to work properly.

WP Starter generates a `wp-config.php` file that reads env variables and declares PHP constants "on the fly" when an env var matching a WP configuration constant is found.

Expand Down Expand Up @@ -131,86 +131,90 @@ There are many places in which such code can be placed, for example a MU plugin.

Alternatively WP Starter can be instructed to do something like this automatically.

The way to go is to use an environment variable called `WP_STARTER_ENV_TO_CONST` that needs to contain a list of of comma-separated list of environment variables that needs to be turned into constants:
### Let WP Starter define constants for custom env vars

WP Starter supports an environment variable called `WP_STARTER_ENV_TO_CONST` containing a list of of comma-separated environment variables to be turned into constants:

```shell
WP_STARTER_ENV_TO_CONST=AWESOME_PLUGIN_CONFIG,ANOTHER_VAR,YET_ANOTHER
WP_STARTER_ENV_TO_CONST="AWESOME_PLUGIN_CONFIG,ANOTHER_VAR,YET_ANOTHER"
```

With such env variable set, WP Start will declare constants for the three env variables.

Please note that env variables are always strings, while PHP constants can be any static type. For WordPress constants that is not an issue because WP Starter knows the expected type can cast the value before define the constant. For custom variables, in case the constant needs to have a different type that can be specified using the syntax: `NAME:TYPE`. For example, having env variables like these:
Please note that env variables are always strings, while PHP constants can be any static type. For WordPress constants that is not an issue because WP Starter knows the expected type can cast the value before define the constant. For custom variables a different type can be specified using the `NAME:TYPE` syntax . For example:

```shell
WP_STARTER_ENV_TO_CONST=AWESOME_PLUGIN_CONFIG:BOOL,ANOTHER_VAR
# This tells WP Starter to create a bool constant for AWESOME_PLUGIN_CONFIG variable
WP_STARTER_ENV_TO_CONST="AWESOME_PLUGIN_CONFIG:BOOL,ANOTHER_VAR"

# This sets the variable that WP Starer will alos turn in a constant
AWESOME_PLUGIN_CONFIG=true
```

WP Starter will define `AWESOME_PLUGIN_CONFIG` as boolean: `define('AWESOME_PLUGIN_CONFIG', true)`.
Having an env file like the above, WP Starter will define `AWESOME_PLUGIN_CONFIG` constant as a boolean, like so:

```php
define('AWESOME_PLUGIN_CONFIG', true):
```



## WP Starter specific env vars
## WP Starter-specific env vars

As described above, all WordPress configuration constants are natively supported by WP Starter.

Moreover, there are a few env variables that have a special meaning for WP Starter.

### DB check env vars

During its bootstrap process, before doing any operation on the system, WP Starter checks if the
environment is already setup for database connection.
If so, WP Starter attempts a connection and launches a very simple SQL command. Thanks to that
it can determine if connection is possible, if the WP DB exists, and if WP is installed.
During its bootstrap process, before doing any operation on the system, WP Starter checks if the environment is already setup for database connection.
If so, WP Starter attempts a connection and launches a very simple SQL command. Thanks to that it can determine if connection is possible, if the WP DB exists, and if WP is installed.

This information is stored in three env vars whose names are stored in
`WeCodeMore\WpStarter\Util\DbChecker` class constants:
This information is stored in three env vars whose names are stored in `WeCodeMore\WpStarter\Util\DbChecker` class constants:

- `DbChecker::WPDB_ENV_VALID` - is non-empty if connection to DB is possible
- `DbChecker::WPDB_EXISTS` - is non-empty if DB exists and is usable
- `DbChecker::WP_INSTALLED` - is non-empty if WordPress is installed

The three env vars are registered in the order they are listed above: if one is non-empty the
previous must be non-empty as well.
The three env vars are registered in the order they are listed above: if one is non-empty the previous must be non-empty as well.

Sometime it might be desirable to bypass this WP Starter check and there's a way to accomplish that
via the `skip-db-check` setting.
Learn more about that in the _"WP-Starter-Configuration"_ chapter.
Sometime it might be desirable to bypass this WP Starter check and there's a way to accomplish that via the `skip-db-check` setting.
Learn more about that in the [_"WP-Starter-Configuration"_ chapter](04-WP-Starter-Configuration.md).

### WordPress Configuration

Those are a few env vars that are used in `wp-config.php` that WP Starter generates.
They are documented in the *"WordPress Integration"* documentation chapter.
They are documented in the [*"WordPress Integration"* chapter](03-WordPress-Integration.md).



## Cached Environment

To parse env files and setup environment variables, and then setup WordPress constants based on the environment, is a bit expensive.

Half of the reason is the env file parsing itself (which can be avoided by setting environment variables in the actual environment). The other half is the fact that WP Starter has no way to know which environment variables matching WP constants are set in the environment before trying to access them. Which means that WP Starter needs to loop **all** the possible WordPress constants, and for each of them try to access an environment variable named in the same way and if that is found finally define a constant.
Half of the reason is the env file parsing itself (which can be avoided by setting environment variables in the actual environment). The other half is the fact that WP Starter has no way to know which environment variables matching WP constants are set in the environment before trying to access them. Which means that WP Starter needs to loop **all** the possible WordPress constants, and for each of them try to access an environment variable named in the same way and define a constant for any found.

To avoid this overhead at every request, the WP Starter `wp-config.php` registers a function to be run on "shutdown" that *dumps* the environment variables that have been accessed with success during the first request into a PHP file so that on subsequent requests the environment "bootstrap" will be much faster.
To avoid this overhead at every request, the WP Starter's `wp-config.php` registers a function to be run on "shutdown" that *dumps* the environment variables that have been accessed with success during the first request into a PHP file so that on subsequent requests the environment "bootstrap" will be much faster.

This cache file is saved in the same folder that contains the `.env` file and is named `.env.cached.php`.

However, having a **cached environment means that any change to it will require the cache file to be deleted**. WP Starter does it via one of its steps ("flush-env-cache") so after a Composer install / update or after running WP Starter command the environment cache is always clean.
However, having a **cached environment means that any change to it will require the cache file to be deleted**. WP Starter does it via one of its steps (["*flush-env-cache*"](05-WP-Starter-Steps.md#flushenvcachestep)), so after every Composer install/update, or after running WP Starter command, the environment cache is always clean.

Of course it is possible to clean env cache on demand by explicitly running the command:
It is also possible to clean environment cache on demand by running the command:

```shell
composer wpstarter flush-env-cache
```

(Read more about running specific steps via `wpstarter` command in the *"WP Starter Command"* chapter)
(Read more about running specific steps via `wpstarter` command in the [*"Command-line interface"* chapter](10-Command-Line-Interface.md))

There are several ways to prevent WP Starter to generate and use cached environment in first place.

- when `WP_ENVIRONMENT_TYPE` env var is `"local"` the cache by default is not created.
- when the **`cache-env`** configuration is `false`, the cache by default is not created.
- there's a WordPress filter `'wpstarter.skip-cache-env'` that can be used to disable the cache creation.

The `'wpstarter.skip.cache-env'` filter is interesting because it allows disabling cache in specific environments by using the **`{$environment}.php`** file described above.
The `'wpstarter.skip.cache-env'` filter is interesting because it allows disabling cache in specific environments, thank to [environment-specific PHP files](03-WordPress-Integration.md#environment-specific-php-file).
For example, it is possible to skip environment cache in "development" environment having a `development.php` file that contains:

```php
Expand Down
Loading

0 comments on commit 54f7a95

Please sign in to comment.