From 865838673a865490f84b2b9bf10a7bc1f12aa41e Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Wed, 16 Feb 2022 16:43:48 -0600 Subject: [PATCH 1/5] Initial work on documenting Data File parser services Replaces #48, credit for initial content to @jaxwilko --- services-parser.md | 235 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/services-parser.md b/services-parser.md index 48ecdf0b..3b3d9468 100644 --- a/services-parser.md +++ b/services-parser.md @@ -11,6 +11,21 @@ - [View mode](#syntax-view-mode) - [Editor mode](#syntax-editor-mode) - [Supported tags](#syntax-supported-tags) +- [Data File Parser: Array](#file-parser-array) + - [Load `ArrayFile`](#array-file-load) + - [Set values](#array-file-set-values) + - [Multidimensional arrays](#array-file-multidimensional-arrays) + - [Default values for `env()` helper](#array-file-env-defaults) + - [Function values](#array-file-function-values) + - [Constant values](#array-file-constant-values) + - [Key sorting](#array-file-key-sorting) + - [Write `ArrayFile`](#array-file-write) + - [Render contents](#array-file-render) +- [Data File Parser: `.env`](#file-parser-env) + - [Setting properties](#setting-properties-env) + - [Writing to a different file than read](#writing-to-a-different-file-env) + - [Adding new lines](#adding-new-lines) + ## Introduction @@ -453,3 +468,223 @@ Multiple line input for larger blocks of text. {textarea name="websiteDescription" label="Website Description"} This is our vision for things to come {/textarea} + + +## Data File Parser: Array + +Winter CMS uses PHP array files (PHP files that do nothing except return a single array) for managing [configuration](../plugin/settings#file-configuration) and [translation data files](../plugin/localization#file-structure). In order to simplify working with these files programatically, Winter provides the `Winter\Storm\Parse\PHP\ArrayFile` parser in the core. + + +### Load `ArrayFile` + +The `ArrayFile` class can be used to modify a PHP array file. The `ArrayFile::open()` method will initialize the `ArrayFile` parser with the contents of the provided path (if the path does not exist it will be created on a call to `$arrayFile->write()`). + +```php +use Winter\Storm\Parse\PHP\ArrayFile; + +$arrayFile = ArrayFile::open('/path/to/file.php'); +$arrayFile->set('foo', 'bar'); +$arrayFile->write(); +``` + + +### Set values + +Setting values can be chained or multiple values can be set by passing an array + +```php +ArrayFile::open('/path/to/file.php') + ->set('foo', 'bar') + ->set('bar', 'foo') + ->write(); + +// or + +ArrayFile::open('/path/to/file.php')->set([ + 'foo' => 'bar', + 'bar' => 'foo' +])->write(); +``` + + +#### Multidimensional arrays + +Multidimensional arrays can be set via dot notation, or by passing an array. + +```php +ArrayFile::open('/path/to/file.php')->set([ + 'foo.bar.a' => 'bar', + 'foo.bar.b' => 'foo' +])->write(); + +// or + +ArrayFile::open('/path/to/file.php')->set([ + 'foo' => [ + 'bar' => [ + 'a' => 'bar', + 'b' => 'foo' + ] + ] +])->write(); +``` + +Will output: + +```php + [ + 'bar' => [ + 'a' => 'bar', + 'b' => 'foo', + ] + ] +]; +``` + + +#### Default values for `env()` helper + +If an array file has a `env()` function call for a given key, setting the value of that key will set the default argument for the call to `env()` rather than replacing the `env()` call altogether. + +For example, if the array file looks like: + +```php + [ + 'bar' => env('EXAMPLE_KEY'), + ] +]; +``` + +And then the following code is used to set the `foo.bar` property: + +```php +ArrayFile::open('/path/to/file.php')->set([ + 'foo.bar' => 'Winter CMS', +])->write(); +``` + +Will result in: + +```php + [ + 'bar' => env('EXAMPLE_KEY', 'Winter CMS'), + ] +]; +``` + + +#### Function values + +Function calls can be added to your config either via the `PHPFunction` class or using the `function()` helper method +on the `ArrayFile` object. + +```php +use Winter\Storm\Parse\PHP\ArrayFile; +use Winter\Storm\Parse\PHP\PHPFunction; + +ArrayFile::open('/path/to/file.php')->set([ + 'foo.bar' => new PHPFunction('env', ['argument1', 'argument1']), +])->write(); + +// or + +$arrayFile = ArrayFile::open('/path/to/file.php'); +$arrayFile->set([ + 'foo.bar' => $arrayFile->function('env', ['argument1', 'argument1']), +]); +$arrayFile->write(); +``` + + +#### Constant values + +Constants can be added to your config either via the `PHPConstant` class or using the `constant()` helper method +on the `ArrayFile` object. + +```php +use Winter\Storm\Parse\PHP\ArrayFile; +use Winter\Storm\Parse\PHP\PHPConstant; + +ArrayFile::open('/path/to/file.php')->set([ + 'foo.bar' => new PHPConstant('PHP_OS'), +])->write(); + +// or + +$arrayFile = ArrayFile::open('/path/to/file.php'); +$arrayFile->set([ + 'foo.bar' => $arrayFile->constant('\Path\To\Class::VALUE'), +]); +$arrayFile->write(); +``` + + +### Key sorting + +The `ArrayFile` object supports sorting the keys used in the file before rendering. + +```php +$arrayFile = ArrayFile::open('/path/to/file.php'); +$arrayFile->set([ + 'b' => 'is awesome' + 'a.b' => 'CMS', + 'a.a' => 'Winter', +]); +$arrayFile->sort(ArrayFile::SORT_ASC); +$arrayFile->write(); +``` + +Will write out: + +```php + [ + 'a' => 'Winter', + 'b' => 'CMS', + ], + 'b' => 'is awesome', +]; +``` + +The sort method supports the following options: + +- `ArrayFile::SORT_ASC` +- `ArrayFile::SORT_DESC` +- a callable function + +By default, `sort()` will use `ArrayFile::SORT_ASC`. + + +### Write `ArrayFile` + +By default, calling `$arrayFile->write()` will write the current state of the `ArrayFile` to the path provided when it was initialized with `ArrayFile::open($path)`. + +If desired, you can specify a different path to write to as the first argument provided to the `write($path)` method: + +```php +ArrayFile::open('/path/to/file.php')->set([ + 'foo.bar' => 'Winter CMS', +])->write('/path/to/another.file.php'); +``` + + +### Render contents + +If you require the PHP `ArrayFile` contents as a string instead of writing directly to a file with `write()`, the `render()` method can be used. + +```php +$phpConfigString = ArrayFile::open('/path/to/file.php')->set([ + 'foo.bar' => 'Winter CMS', +])->render(); +``` From 349f84f199b29e1216122babd7e12d6709488bf9 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Wed, 16 Feb 2022 21:52:07 -0600 Subject: [PATCH 2/5] Finish EnvFile docs --- services-parser.md | 112 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 4 deletions(-) diff --git a/services-parser.md b/services-parser.md index 3b3d9468..451d9976 100644 --- a/services-parser.md +++ b/services-parser.md @@ -22,10 +22,11 @@ - [Write `ArrayFile`](#array-file-write) - [Render contents](#array-file-render) - [Data File Parser: `.env`](#file-parser-env) - - [Setting properties](#setting-properties-env) - - [Writing to a different file than read](#writing-to-a-different-file-env) - - [Adding new lines](#adding-new-lines) - + - [Set values](#env-file-set-values) + - [Empty lines](#env-file-empty-lines) + - [Write `EnvFile`](#env-file-write) + - [Render contents](#env-file-render) + - [Get variables](#env-file-get-variables) ## Introduction @@ -688,3 +689,106 @@ $phpConfigString = ArrayFile::open('/path/to/file.php')->set([ 'foo.bar' => 'Winter CMS', ])->render(); ``` + + +## Data File Parser: `.env` + +Winter supports the use of [DotEnv](https://github.com/vlucas/phpdotenv) files (`.env`) to manage environment specific variables. + +Getting these values is as easy as using the [`env()` helper function](https://wintercms.com/docs/services/helpers#method-env). Winter also provides a way to programmatically set the values in the `.env` file through the use of the `Winter\Storm\Parse\EnvFile` parser in the core. + + +## Load `EnvFile` + +The `EnvFile` class can be used to modify a PHP array file. The `EnvFile::open()` method will initialize the `EnvFile` parser with the contents of the provided path (if the path does not exist it will be created on a call to `$envFile->write()`). + +By default, the `.env` file interacted with will be `base_path('.env')`, this can be changed if required by passing the path to the `open()` method. + + +## Set values + +Values can be set either one at a time or by passing an array of values to set. + +```php +$env = EnvFile::read(); +$env->set('FOO', 'bar'); +$env->set('BAR', 'foo'); +$env->write(); + +// or + +EnvFile::read()->set([ + 'FOO' => 'bar' + 'BAR' => 'foo' +])->write(); +``` + +> NOTE: Array dot notation and nested arrays are not supported by `EnvFile` + +```php +use Winter\Storm\Config\EnvFile; + +$env = EnvFile::read(); +$env->set('FOO', 'bar'); +$env->write(); +``` + +> NOTE: Values are set in the order they are provided, automatic sorting is not currently supported because comments and empty lines make that a lot more complex. + + +#### Empty lines + +It is also possible to add empty lines into the env file, usually for organizational purposes: + +```php +$env = EnvFile::read(); +$env->set('FOO', 'bar'); +$env->addEmptyLine(); +$env->set('BAR', 'foo'); +$env->write(); +``` + +Will output: + +```dotenv +FOO="bar" + +BAR="foo" +``` + + +### Write `EnvFile` + +By default, calling `$envFile->write()` will write the current state of the `EnvFile` to the path provided when it was initialized with `EnvFile::open($path)`. (defaulting to `base_path('.env')` when no `$path` is provided). + +If desired, you can specify a different path to write to as the first argument provided to the `write($path)` method: + +```php +EnvFile::read()->set([ + 'FOO' => 'bar', +])->write('/path/to/.env.alternative'); +``` + + +### Render contents + +If you require the `EnvFile` contents as a string; instead of writing directly to a file with `write()`, the `render()` method can be used. + +```php +$envFileString = EnvFile::open()->set([ + 'APP_NAME' => 'Winter CMS', +])->render(); +``` + + +### Get variables + +The `EnvFile` parser provides a `getVariables()` method that can be used to get an associative array of the current variables excluding any comments or empty lines. + +```php +$envVariables = EnvFile::open()->set([ + 'APP_NAME' => 'Winter CMS', +])->getVariables(); + +echo $envVariables['APP_NAME']; // echos "Winter CMS" +``` From 3290aa2700f6640eedd272cfc6188646d1ba54fd Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Wed, 16 Feb 2022 22:58:40 -0600 Subject: [PATCH 3/5] Document $throwIfMissing --- services-parser.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services-parser.md b/services-parser.md index 451d9976..84d61fd5 100644 --- a/services-parser.md +++ b/services-parser.md @@ -488,6 +488,8 @@ $arrayFile->set('foo', 'bar'); $arrayFile->write(); ``` +The `ArrayFile::open()` method accepts a second argument `$throwIfMissing` that defaults to `false`. If `true`, a `\InvalidArgumentException` will be thrown if the provided `$filePath` does not point to an existing file. + ### Set values From 9dfe44497bd2445c37ce479035fcb9bb40869316 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Thu, 17 Feb 2022 10:13:38 -0600 Subject: [PATCH 4/5] fix links --- services-parser.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services-parser.md b/services-parser.md index 84d61fd5..eb56cbb7 100644 --- a/services-parser.md +++ b/services-parser.md @@ -470,12 +470,12 @@ Multiple line input for larger blocks of text. This is our vision for things to come {/textarea} - + ## Data File Parser: Array Winter CMS uses PHP array files (PHP files that do nothing except return a single array) for managing [configuration](../plugin/settings#file-configuration) and [translation data files](../plugin/localization#file-structure). In order to simplify working with these files programatically, Winter provides the `Winter\Storm\Parse\PHP\ArrayFile` parser in the core. - + ### Load `ArrayFile` The `ArrayFile` class can be used to modify a PHP array file. The `ArrayFile::open()` method will initialize the `ArrayFile` parser with the contents of the provided path (if the path does not exist it will be created on a call to `$arrayFile->write()`). From 70ef059c0b6693bde5277e544ee6cf1e892886f5 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 15 Mar 2022 21:48:22 -0600 Subject: [PATCH 5/5] Apply suggestions from code review --- services-parser.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services-parser.md b/services-parser.md index eb56cbb7..1b32c965 100644 --- a/services-parser.md +++ b/services-parser.md @@ -712,14 +712,14 @@ By default, the `.env` file interacted with will be `base_path('.env')`, this ca Values can be set either one at a time or by passing an array of values to set. ```php -$env = EnvFile::read(); +$env = EnvFile::open(); $env->set('FOO', 'bar'); $env->set('BAR', 'foo'); $env->write(); // or -EnvFile::read()->set([ +EnvFile::open()->set([ 'FOO' => 'bar' 'BAR' => 'foo' ])->write(); @@ -730,7 +730,7 @@ EnvFile::read()->set([ ```php use Winter\Storm\Config\EnvFile; -$env = EnvFile::read(); +$env = EnvFile::open(); $env->set('FOO', 'bar'); $env->write(); ``` @@ -743,7 +743,7 @@ $env->write(); It is also possible to add empty lines into the env file, usually for organizational purposes: ```php -$env = EnvFile::read(); +$env = EnvFile::open(); $env->set('FOO', 'bar'); $env->addEmptyLine(); $env->set('BAR', 'foo'); @@ -766,7 +766,7 @@ By default, calling `$envFile->write()` will write the current state of the `Env If desired, you can specify a different path to write to as the first argument provided to the `write($path)` method: ```php -EnvFile::read()->set([ +EnvFile::open()->set([ 'FOO' => 'bar', ])->write('/path/to/.env.alternative'); ```